我想在类属性中嵌套一些函数,如下所示 不幸的是,他们无法访问该课程的主要范围。
我是否可以在不将每个嵌套函数传递给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
使用建议的胖箭头的非工作替代方案:
class myClass
constructor: ->
@errors = []
@functions:
doStuff: =>
@errors.push "I wont work either" # TypeError: Cannot call method 'toString' of undefined
可选替代,不写入全局this.errors
属性:
class myClass
constructor: ->
@functions =
errors: []
doStuff: ->
@errors.push "I will write to functions.errors only"
答案 0 :(得分:3)
在JavaScript中(结果也是CoffeeScript),方法使用包含方法的对象的this
。
method() // this == globalObject
object.method() // this == object
Math.random() // this == Math
这通常很有效,除非你处理像你这样的例子:
object.functions.method() // this == object.functions
在处理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!"
这似乎首先起作用,但当您使用apply
或call
等属性时可能会造成混淆,obj1.functions.alsoDoSomething.call(obj2)
无法用作obj2
是不正确的对象(用户应该做obj2.functions
而不是混淆)。
真正的解决方案是:不。 JavaScript不会像这样滥用。所有对象方法都应该直接在对象原型中。如果你有对象,它的所有方法都不是你对象的方法。
答案 1 :(得分:2)
作为GlitchMr答案的附录,我将解释为什么你的每次尝试都失败了。
functions
对象在原型上声明,因此@errors
被编译为myClass.errors
。但是,errors
对象被声明为实例成员,而不是原型成员。functions
,它应该是一个对象。错误消息是CoffeeScript编译器错误;修复此语法错误后,它的工作原理应该如此!以下是在这种情况下正确使用fat arrow的示例。
class MyClass
constructor: ->
@errors = []
@functions =
doStuff: =>
@errors.push "I can and do access @errors"
c = new MyClass
c.functions.doStuff()
console.log c.errors # ["I can and do access @errors"]
希望这有助于揭开错误的神秘面纱,展现出CoffeeScript肥胖箭头的力量!