为什么';这个CoffeeScript/JavaScript设置创建对象的属性吗?

为什么';这个CoffeeScript/JavaScript设置创建对象的属性吗?,javascript,coffeescript,Javascript,Coffeescript,我有以下两个CoffeeScript类定义。我希望他们也有同样的行为,但他们没有。尤其是在doesnowork实例上访问A是未定义的 fields = ["A","B","C"] class DoesNotWork constructor: () -> _.each(fields, (f) -> @[f] = ko.observable('')) class DoesWork constructor: () -> @A = ko.observable

我有以下两个CoffeeScript类定义。我希望他们也有同样的行为,但他们没有。尤其是在
doesnowork
实例上访问
A
是未定义的

fields = ["A","B","C"]

class DoesNotWork
  constructor: () ->
    _.each(fields, (f) -> @[f] = ko.observable(''))

class DoesWork
  constructor: () ->
    @A = ko.observable('')
    @B = ko.observable('')
    @C = ko.observable('')
以上代码编译为

var DoesNotWork, DoesWork, fields;
fields = ["A", "B", "C"];
DoesNotWork = (function() {
  function DoesNotWork() {
    _.each(fields, function(f) {
      return this[f] = ko.observable('');
    });
  }
  return DoesNotWork;
})();
DoesWork = (function() {
  function DoesWork() {
    this.A = ko.observable('');
    this.B = ko.observable('');
    this.C = ko.observable('');
  }
  return DoesWork;
})();

我遗漏了什么新手JS?

在传递给的匿名函数中“this”。每个都绑定到匿名函数,而不是父对象。每个都允许传递一个上下文对象,这样就可以正确地绑定它

因此,在每个参数的第3个参数中向您尝试绑定的对象传递一个引用:

class ShouldWorkNow
  constructor: () ->
    _.each(fields, ((f) -> @[f] = ko.observable('')),this)

Craig的答案是正确的,但另一种解决方案是将匿名函数定义为一个。在这种情况下,这将让你写

_.each(fields, ((f) => @[f] = ko.observable('')))
=>
将函数绑定到定义它的上下文中,因此
在函数中始终意味着相同的内容,无论如何调用它。对于回调来说,这是一种非常有用的技术,尽管在
的情况下,每个
都比传入
这个
的效率要低一些

你也可以用下划线来写

callback = _.bind ((f) -> @[f] = ko.observable('')), this
_.each(fields, callback)
但是
=>
为您节省了大量的打字时间

另一个解决方案(可以说是可读性和效率最高的)是跳过
每个
都使用CoffeeScript的
进行迭代:

for f in fields
  @[f] = ko.observable ''
您甚至可以对循环进行后缀,使其成为一行:

@[f] = ko.observable('') for f in fields

记住,CoffeeScript中的循环不会创建上下文或影响范围;只有函数才可以。

函数应该在
()
中。它应该是:
.each(fields,((f)->@[f]=ko.observable(“”)),this)
@Rocket:谢谢,我刚刚复制了示例中的代码。修正。一个小的修正:
默认情况下,此
不绑定到匿名函数,而是绑定到全局上下文,就像您编写
func.call null,
时一样。您几乎不需要
\在咖啡脚本中使用每个
。我强烈建议改为使用
for/in
。它确实有效。。。它只是做不到你想让它做的事。这两个答案都是很好的选择。可惜没有一个集合。每个集合都内置在coffeescript中,很像Ruby。下划线在修补这种风格方面做得很好,但对咖啡脚本的理解却相当流畅。我想我更喜欢前面的循环机制,而不是拖尾(旧的c习惯),对吧,CoffeeScript不会修改原型。如果希望阵列上的每个
方法都有一个
,则可以将CoffeeScript与结合使用。