Reputation: 719
I'm reading Nicholas Z.Zakas' Professional JavaScript for web developer 3rd edition and inside the Reference types chapter I got a bit confused at the function type part.
function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments);
}
alert(callSum1(10,10)); //20
"In this example, callSum1()
executes the sum()
method, passing in this
as the this
value (which is equal to window
because it's being called in the global scope) and also passing in the arguments
object."
I understand what he says, but I don't understand the why. This
supposed to point to the function doesn't it? Now I'm confused that it's pointing to the window because it's being called in the global scope ..
Can someone be kind to explain it to me? :)
I'm not sure if I will or I have to use this technique later, but I want to make sure I understand it, especially the this part. More details about this
and its usage will come in the OOP section, but it's now an interesting question.
Thanks in advance!
Upvotes: 0
Views: 166
Reputation: 719
Under the Window object part ~20 pages later, I'm reading this: "As mentioned previously, the this
value is equivalent to the Global object when a function is executed with no explicit this
value specified (either by being an object method or via call()
/apply()
)." :)
Maybe I didn't get it before, but now it's clear with his words as well. By the way, the book is awesome! Now with Math object I can understand much more the apply() method, too.
var values = [1,2,3,4,5,6];
var max = Math.max.apply(Math, values);
Upvotes: 0
Reputation: 1074218
Here:
alert(callSum1(10,10)); //20
...you're calling callSum
without doing anything to set this
during the call, and so this
is defaulted to the global object (window
, on browsers). (In loose mode; in strict mode, this
would have been undefined
.)
Since you're then using apply
and passing that same this
into it:
return sum.apply(this, arguments);
...naturally the global object is also used when calling sum
.
I understand what he says, but I don't understand the why. This supposed to point to the function doesn't it?
No, this
almost never refers to functions. (It can, of course, it just very rarely does.)
Now I'm confused that it's pointing to the window because it's being called in the global scope ..
It's not because it's being called in the global scope; it would be the same if it were being called from inside a function. What matters isn't where the call occurs, but how. Any time you call a function without doing anything to set this
, in loose mode, this
during the function call will be the global object. It doesn't have to be at global scope; what matters is how you call the function.
The rule is actually a lot simpler than people make it out to be: If you call a function without doing anything to set this
, during the call, this
will be the global object (in loose mode) or undefined
(in strict mode). Here are the things you can do to set this
during a function call:
Call the function as part of an expression getting the function from a property on an object. For example, foo.bar();
retrieves a reference to the function from the bar
property on foo
, then calls bar
. Because we did it that way, during the call to bar
, this
refers to foo
.
Call the function using .call
or .apply
; this
will be what you pass in the first argument. (In loose mode, if you pass undefined
, null
, or a non-object in the first argument, during the call this
will be the global object. In strict mode, it'll be what you pass.)
Call a bound function. That's a function created via Function#bind
(an ES5 feature). Bound functions have this
"baked into" them.
More (on my blog):
Upvotes: 1
Reputation: 943480
The value of this
depends on how you call a function.
If you call a function using call
or apply
then the value of this
will be the first argument to that function.
Here you have sum.apply(this, arguments);
so it will pass the current value through. As usual, that value is determined by how you call the function.
Since you call callSum1(10,10)
with no context, this
will be window
.
(If you were in strict mode, it would be undefined
. If you weren't in a browser, it would be whatever the default object of the JS environment you were using was).
Upvotes: 3