3

我有以下两个 CoffeeScript 类定义。我希望他们有同样的行为,但他们没有。特别是A对实例的访问DoesNotWork是未定义的。

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?

4

3 回答 3

6

Yet another solution (arguably the most readable and efficient) is to skip _.each and instead use CoffeeScript's for...in iteration:

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

You could even postfix the loop to make it a one-liner:

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

Remember that loops in CoffeeScript don't create context or affect scope; only functions do.

于 2011-03-29T20:32:29.027 回答
4

传递给 _.each 的匿名函数中的“this”绑定到匿名函数,而不是父对象。_.each 确实允许传递一个上下文对象,以便正确绑定它

http://documentcloud.github.com/underscore/#each

因此,将 ref 传递给您尝试在每个对象的第三个参数中绑定的对象:

class ShouldWorkNow
  constructor: () ->
    _.each(fields, ((f) -> @[f] = ko.observable('')),this)
于 2011-03-29T17:57:26.637 回答
3

Craig's answer is correct, but an alternative solution is to define your anonymous function as a bound function. In this case, that would let you write

_.each(fields, ((f) => @[f] = ko.observable('')))

The => binds the function to the context in which it's defined, so that this always means the same thing in the function no matter how it's called. It's a very useful technique for callbacks, though in the case of _.each, it's a bit less efficient than passing this in.

You could do the same thing using Underscore by writing

callback = _.bind ((f) -> @[f] = ko.observable('')), this
_.each(fields, callback)

but => saves you a lot of typing!

于 2011-03-29T20:28:04.537 回答