Почему этот CoffeeScript / JavaScript не устанавливает свойства созданного объекта? - PullRequest
3 голосов
/ 29 марта 2011

У меня есть два следующих определения класса 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 тонко мне не хватает?

Ответы [ 3 ]

6 голосов
/ 30 марта 2011

Еще одно решение (возможно, наиболее читаемое и эффективное) - пропустить _.each и вместо этого использовать итерацию CoffeeScript for...in:

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

Вы можете даже добавить в цикл цикл, чтобы сделать его однострочным:

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

Помните, что циклы в CoffeeScript не создают контекста и не влияют на область видимости; делают только функции.

4 голосов
/ 29 марта 2011

'this' в анонимной функции, переданной в _.each, привязано к анонимной функции, а не к родительскому объекту. _.each позволяет передавать объект контекста, чтобы он был правильно связан, хотя

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

, поэтому передайте ссылку на объект, к которому вы пытаетесь привязаться, в 3-м аргументе каждого:

class ShouldWorkNow
  constructor: () ->
    _.each(fields, ((f) -> @[f] = ko.observable('')),this)
3 голосов
/ 30 марта 2011

Ответ Крейга верный, но альтернативное решение - определить вашу анонимную функцию как связанную функцию .В этом случае это позволит вам написать

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

. => связывает функцию с контекстом, в котором она определена, так что this всегда означает одно и то же в функции независимо от того, как онаназывается.Это очень полезный метод для обратных вызовов, хотя в случае _.each он немного менее эффективен, чем передача this in.

Вы можете сделать то же самое, используя Underscore, написав

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

но => сэкономит вам много печатать!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...