coffeescript课程的范围

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)

Kon*_*ski 3

在 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 不适合这样的滥用。所有对象方法都应该直接位于对象原型中。如果其中有对象,则它的所有方法都不是对象的方法。