范围在coffeescript类 [英] Scope in coffeescript classes

查看:104
本文介绍了范围在coffeescript类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在类属性中嵌套一些函数,如下所示。

不幸的是,他们无法访问类的主要范围。

I would like to nest a number of functions inside a class property as shown below.
Unfortunately, they won't get access to the main scope of the class.

我可以解决这个问题,但不会传递每个嵌套函数对这个

Can I solve this without passing each nested function a reference to 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

使用建议的脂肪箭头的非工作替代:

Non-working alternative using suggested fat arrow:

class myClass
  constructor: ->
    @errors = []

    @functions:
      doStuff: =>
        @errors.push "I wont work either" # TypeError: Cannot call method 'toString' of undefined


$ b b

可选备选项,不会写入全局 this.errors 属性:

class myClass

  constructor: ->

    @functions =
      errors: []
      doStuff: ->
        @errors.push "I will write to functions.errors only"


推荐答案

在JavaScript中(因此,CoffeeScript也),方法使用包含方法的对象的 this

In JavaScript (as the result, CoffeeScript too), methods use this of the object that contains method.

method()                  // this == globalObject
object.method()           // this == object
Math.random()             // this == Math

这通常很有效,除非你处理像yours这样的例子:

This usually works well, unless you deal with example like yours:

object.functions.method() // this == object.functions

在处理JavaScript时,我会避免使用函数的命名空间 - 即使有解决方法也不能很好地播放。例如,您可以尝试在 object.functions 中引用对象,因此<$ c $中的任何函数c> object.functions 可以访问它。

When dealing with JavaScript, I would avoid having namespace for functions - it doesn't play well, even with workarounds. For example, you could try putting reference to this object in object.functions, so any function in object.functions would have access to it.

class MyClass
  constructor: ->
    @errors = []
    @functions.self = this

  doSomething: ->
    @errors.push "I work as expected"

  functions:
    alsoDoSomething: ->
      @self.errors.push "Also works!"

这看起来工作起来很好,但是当你使用应用调用 obj1.functions.alsoDoSomething.call(obj2)将无法工作,因为 obj2 是不正确的对象(用户应该做 obj2.functions )。

This appears to work at first, but could be confusing when you are using properties like apply or call on it, obj1.functions.alsoDoSomething.call(obj2) won't work as the obj2 is not correct object (user should do obj2.functions instead which can be confusing).

真正的解决方案是:不要。 JavaScript不是为这样的滥用。所有对象方法都应该直接在对象原型中。如果你有对象,它的所有方法都不是你的对象的方法。

The real solution is: don't. JavaScript isn't intended for abuse like this. All object methods should be directly in object prototype. If you have object in it, all methods of it aren't methods of your object.

这篇关于范围在coffeescript类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆