Ind*_*ial 9 javascript scope coffeescript
我想在类属性中嵌套许多函数,如下所示.
不幸的是,他们无法访问该课程的主要范围.
我可以在不传递每个嵌套函数的情况下解决这个问题this吗?
class myClass
constructor: -> @errors = []
doSomething: -> @errors.push "I work as expected"
functions:
doStuff: ->
@errors.push "I cant access @errors" # => TypeError: Cannot call method 'push' of undefined
ugly: (context) ->
context.errors.push "It works, but I am ugly" # Works fine but requires scope injection
Run Code Online (Sandbox Code Playgroud)
使用建议的胖箭头的非工作替代方案:
class myClass
constructor: ->
@errors = []
@functions:
doStuff: =>
@errors.push "I wont work either" # TypeError: Cannot call method 'toString' of undefined
Run Code Online (Sandbox Code Playgroud)
可选的替代方法,它不会写入全局this.errors属性:
class myClass
constructor: ->
@functions =
errors: []
doStuff: ->
@errors.push "I will write to functions.errors only"
Run Code Online (Sandbox Code Playgroud)
在 JavaScript 中(因此,CoffeeScript 也是如此),方法使用this包含方法的对象。
method() // this == globalObject
object.method() // this == object
Math.random() // this == Math
Run Code Online (Sandbox Code Playgroud)
这通常效果很好,除非你处理像你这样的例子:
object.functions.method() // this == object.functions
Run Code Online (Sandbox Code Playgroud)
在处理 JavaScript 时,我会避免使用函数的命名空间 - 即使有解决方法,它也不能很好地发挥作用。例如,您可以尝试将对this对象的引用放入 中object.functions,因此 中 的任何函数都object.functions可以访问它。
class MyClass
constructor: ->
@errors = []
@functions.self = this
doSomething: ->
@errors.push "I work as expected"
functions:
alsoDoSomething: ->
@self.errors.push "Also works!"
Run Code Online (Sandbox Code Playgroud)
这看起来一开始是有效的,但是当您使用类似apply或 的属性时call,可能会感到困惑obj1.functions.alsoDoSomething.call(obj2),因为obj2对象不正确(用户应该obj2.functions这样做,这可能会令人困惑),所以不会起作用。
真正的解决方案是:不要。JavaScript 不适合这样的滥用。所有对象方法都应该直接位于对象原型中。如果其中有对象,则它的所有方法都不是对象的方法。