5

I am a beginner in js, and am puzzled by the following code:

Foo = function(arg) {
 this.arg = arg;
};
Foo.prototype = {
 init: function () {
 var f = function () {
 alert("current arg: " + this.arg); // am expecting "bar", got undefined
 }
 f();
 }
};
var yo = Foo("bar");
yo.init();

I was expected to get "current arg: bar", but got "current arg: undefined". I noticed that by copying this.arg into a "normal" variable first, and refering this variable in the closure works:

Foo.prototype = {
 init: function () {
 var yo = this.arg;
 var f = function () {
 alert("current arg: " + yo); }
 f();
 }
};

Am I doing something wrong, got wrong expectations, or does it fall into one of the js WTF ?

asked Nov 12, 2010 at 5:39
2
  • Copying this.arg into a "normal" variable first won't do anything different to what this means for your function. Commented Nov 12, 2010 at 6:02
  • @bobobobo Technically true, but when did anyone imply that would happen? The way you phrased that could be misleading. He did not in fact use this in the second example; using the local variable yo creates a closure that keeps the reference to the intended object even inside the f function. Commented Nov 12, 2010 at 6:09

2 Answers 2

4

Vanilla functions will be run with this referring to window. Your second piece of code is a perfect example of how to work around this problem using closures.

(You can also use call and apply to call a function with a particular context.)

answered Nov 12, 2010 at 5:45
Sign up to request clarification or add additional context in comments.

1 Comment

It's too bad downvotes are anonymous. To whomever downvoted, I'd appreciate a comment :)
3

It depends on how the function was invoked.

If invoked with keyword new then this refers to the object being constructed (which will be implicitly returned at the end of the function).

If invoked as a normal function, this refers to the global window object.

Example:

// Constructor for Foo,
// (invoke with keyword new!)
function Foo()
{
 this.name = "Foo" ;
}
myFoo = new Foo() ;
alert( 'myFoo ' + myFoo.name + '\n' + 'window: ' + window.name ) ; // window.name will be empty
// now if we invoke Foo() WITHOUT keyword NEW
// then all references to `this` inside the
// function Foo will be to the
// __global window object__, i.e. the global window
// object will get clobbered with new properties it shouldn't
// have! (.name!)
Foo() ; // incorrect invokation style!
alert( 'myFoo ' + myFoo.name + '\n' + 'window: ' + window.name ) ;

JavaScript doesn't have "constructors" per se, the only way JavaScript knows that your function is actually a "constructor" is invokation style (namely you using keyword new whenever you invoke it)

answered Nov 12, 2010 at 5:55

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.