this is different from JavaScript than in some other languages ββsuch as C ++ or Java. The value of this in your first example will always be a global object ( window , in browsers). this in your second example is the jsn object for the first warning, and window is the second. This is because this completely determined by how the function is called, and not where it is defined.
If you are not doing anything special when calling a function, this is a global object. When you call a function through an object property ( jsn.func() ), this set to the object from which the property emanates. (But make no mistake, func is not tied to jsn in any way; JavaScript has no methods, just functions; details .) f1 then returns a function that is called in the final alert ; since this call is not made through an object property, this set to the global object.
Some examples:
// Simple function function foo() { alert(this === window); } foo(); // true, within the call, `this` === `window` // Object example, and twist at the end var obj = { func: function() { alert(this === obj); }, }; obj.func(); // true, within the call, `this` === `obj` obj["func"](); // true, within the call, `this` === `obj` var f = obj.func; // Not calling it, just getting a reference to the function f(); // false, within the call `this` !== `obj` (`this` === `window`) // Creating functions on the fly, returning them, and how that has // nothing whatsoever to do with how `this` gets set: var obj = { func: function() { return function() { alert("I'm a generated function"); alert(this === obj); }; } }; obj.func()(); // alerts the "I'm a generated function", then false; `this` !== `obj` obj.bar = obj.func(); obj.bar(); // alerts the "I'm a generated function", then true; `this` === `obj`
There is a second way to control that this is inside the function: use the .call or .apply functions of the JavaScript functions:
var obj = { func: function() { alert(this === obj); } }; function foo(a, b) { alert(this === obj); // Yes, really obj; see below alert(a); alert(b); } foo(1, 2); // alerts false (`this` !== `obj`), then 1, then 2 obj.func(); // alerts true, `this` === `obj` foo.call(obj, 3, 4); // alerts true (`this` === `obj`), then 3, then 4 foo.apply(obj, [5, 6]); // alerts true (`this` === `obj`), then 5, then 6
As you can see, the first argument to call or apply is the object that does this inside the function call. The only difference between call and apply is how you specify the arguments to pass to the target function: With call you simply send them after the first argument; with application, you supply them as an array.
And finally, there is a third way: the new keyword. JavaScript has a concept of design functions. The purpose of the constructor function is to instantiate objects that are initialized in a specific way. Here is an example:
function Foo(b) { this.bar = b; } var f = new Foo();
Technically, any function can be used as a constructor function. The agreement is to provide functions intended for use with new names starting with a capital letter, only to enhance them, which we call them in a special way.
The function call through new creates a new instance of the object and makes this object the value of this in the function call. So
function Foo(b) { alert(this === window); } var f = new Foo(); // alerts false, `this` !== `window` (it points to the new object created for the call) var f = Foo(); // alerts true, `this` === `window` because we didn't use `new`
As you can see, it is important to call the function correctly. If it is intended for use with new , call it through new ; if not, do not do this.
( new does more than just create an empty object; the created object has some other aspects defined in a certain way. I will not go into details here, but I did not want to leave you with the impression that all he did was create a new instance of the object.)