0

The following script produces "Hello", "undefined", "Hello" message boxes:

function action(callback) {
  window.setTimeout(callback, 1000);
}

var obj = { 
  text: "Hello", 
  f: function() { window.alert(this.text); } 
};

obj.f(); // Line 1
action(obj.f); // Line 2
action(function() { obj.f(); }); // Line 3

I looking for explanation why the line marked as "Line 2" produces "undefined" output.

LicenseQ
  • 1,721
  • 1
  • 15
  • 21
  • 1
    Best answers on `this` topic: http://stackoverflow.com/questions/80084/in-javascript-why-is-the-this-operator-inconsistent/80478#80478 and http://stackoverflow.com/questions/541167/what-is-the-rationale-for-the-behavior-of-the-this-keyword-in-javascript/542060#542060 – Crescent Fresh Nov 18 '09 at 02:44
  • The first reference is really good one – LicenseQ Nov 18 '09 at 02:53

4 Answers4

3

in JavaScript, this is not bound to the method (like in python). Line 2 results in just the function being called, and this is undefined or not obj

Knio
  • 6,638
  • 3
  • 29
  • 29
2

When you call line2: You are only passing the function into the parameter. Since you are only passing the function, not the whole object, when it is called, this in the function does not refer to obj, thus making this.text undefined.

mauris
  • 42,982
  • 15
  • 99
  • 131
1

Alot of JS libraries do something like this:

if (!Function.prototype.context) {
    Function.prototype.context = function (object) {
        var fn = this;
        return function () { return fn.apply(object, arguments); };
    };
}

To be able to pass/bind this to a handler. So in your case you can do smthg like this

action(obj.f.context(obj));

and receive your 'Hello'. And yes, this is a general way to do something you done in step 3.

NilColor
  • 3,462
  • 3
  • 30
  • 44
0

The second one you pass a function with no scope so this becomes the highest object in the scope chain. The third way you create a closure and call f on the object directly which leaves this with the proper scope.

ChaosPandion
  • 77,506
  • 18
  • 119
  • 157