I'm not sure where this points in JavaScript. And I give 2 examples.
Can you help me analyze them? Thank you very much.
//exmp1
function f1()
{
alert(this);
function f2()
{
alert(this);
}
f2();
}
f1();
//exmp2
var jsn =
{
name : "b",
func : function() // closure
{
alert(this);
return function()
{
return this;
}
}
}
alert(jsn.func()());
this
is different in JavaScript than it is in some other languages like C++ or Java. The value of this
in your first example will always be the global object (window
, on browsers). this
in your second example is the jsn
object for the first alert, and window
for the second. This is because this
is determined entirely by how a function is called, not where it's defined.
If you don't do anything special when calling the function, this
is the global object. When you call a function via an object property (jsn.func()
), this
is set to the object the property came from. (But don't get the wrong impression, func
is in no way specially tied to jsn
; JavaScript doesn't have methods, just functions; details.) f1
then returns a function, which is called within the final alert
; since that call is not via an object property, this
is 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's a second way to control what this
is within a function: Use the .call
or .apply
features of 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 to make this
within the function call. The only difference between call
and apply
is how you specify arguments to pass into the target function: With call
, you just supply them after the first argument; with apply, you supply them as an array.
And finally, there's a third way: The new
keyword. JavaScript has the concept of constructor functions. The purpose of a constructor function is to create instances of objects initialized in a particular way. Here's an example:
function Foo(b) {
this.bar = b;
}
var f = new Foo();
Technically, any function can be used as a constructor function. The convention is to give functions meant to be used with new
names starting with a capital letter, just to reinforce that we call them in a special way.
Calling a function via new
creates a new object instance and makes that object the this
value within 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's important to call a function in the correct way. If it's designed to be used with new
, call it via new
; if it's not, don't.
(new
does more than just create a blank object; the object created has some other aspects set up in a certain way. I won't go into the details here, but I didn't want to leave you with the impression that all it did was create a new object instance.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With