Bob
Bob

Reputation: 8504

Underscore.js why is this undefined

I am learning Underscore.js, see this code snippet

  var obj = function() {
    var foo = 1;
  }
  _(obj).extend({
    a: function(){
      var foo = 2;
      console.log("this.foo=" + this.foo + "\nthis=" + this + "\nfoo=" + foo + "\n\n");
    }
  });
  console.log("obj.a="+obj.a()+"\nobj="+obj);

The console output is

this.foo=undefined
this=function () {
    var foo = 1;
  }
foo=2

obj.a()=undefined
obj=function () {
    var foo = 1;
  } 

Why are this.foo and obj.a() and undefined?

Upvotes: 0

Views: 831

Answers (2)

Andy Novocin
Andy Novocin

Reputation: 454

If you want this.foo and foo to line up you might want to use something like this:

  var foo = 2;

  var Obj = function() {
      var foo = 1;
  }

  var obj = _.extend(new Obj(), {
    foo : foo, 
    a: function(){
       console.log("this.foo=" + this.foo + "\nthis=" + this + "\nfoo=" + foo + "\n\n");
       return this.foo;
    }
  });
  console.log("obj.a="+obj.a()+"\nobj="+obj);

This gives output:

this.foo=2
this=[object Object]
foo=2

obj.a=2
obj=[object Object] 

There were a few issues with the original code:

  1. _.extend is the way to call the function you desired, _ is the namespace and extend is the method name.
  2. The output of _.extend is a copy, not an in-place replacement, so you should save the output as obj or some other variable name.
  3. foo and this.foo are different. this.foo is an attribute of the object (nameless object) which has the method a while var foo is a local variable inside of the a method.
  4. If the above are fixed (for some version of the word fixed) then obj.a() has an undefined output because there is no return value.
  5. obj the way you defined it was a function, but also essentially a class definition.

Adjustments: 1. I converted obj to Obj to signify it's status as a class.
2. I added var foo to the same namespace that has Obj. 3. In the call to _.extend I instantiate an Obj. 4. I synced var foo (temporarily) with this.foo by making it an attribute of the nameless object which you are extending with an Obj instance.
5. Saved the output of _.extend as obj.
6. I gave the method a a return value (I chose this.foo).

Here is a working fiddle, note that the output is to the console.

Upvotes: 2

Jacob Krall
Jacob Krall

Reputation: 28825

this.foo is undefined because var foo defines a variable in local scope, not a property of the object.

obj.a() is undefined because you do not return anything in the declared function.

Upvotes: 2

Related Questions