Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this CoffeeScript/JavaScript set the properties of created object?

I've the following two CoffeeScript class definitions. I expected them to the same behavior, but they don't. In particular accessing A on instances of DoesNotWork is undefined.

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('')

the above code compiles to

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;
})();

What newbie JS subtly am I missing?

like image 439
Scott Weinstein Avatar asked Dec 06 '25 16:12

Scott Weinstein


2 Answers

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.

like image 185
Trevor Burnham Avatar answered Dec 08 '25 04:12

Trevor Burnham


'this' in the anonymous function passed to _.each is bound to the anonymous function, not the parent object. _.each does allow passing a context object so that this will be bound properly though

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

so pass a ref to the object you are trying to bind to in the 3rd arg of each:

class ShouldWorkNow
  constructor: () ->
    _.each(fields, ((f) -> @[f] = ko.observable('')),this)
like image 33
Craig Avatar answered Dec 08 '25 04:12

Craig



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!