Recently one of my friends asked me the output of following code
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1);
I thought the answer would be 10 10 but surprisingly for second call i.e. arguments[0]();
the value comes out to be 2 which is length of the arguments passed.
In other words it seems arguments[0]();
has been converted into fn.call(arguments);
.
Why this behavior? Is there a link/resource for such a behavior?
Answer
The difference is because of the this
context of each method call.
In the first instance, because the call is merely fn();
, the this
context is Window
. The var length = 10;
variable declaration at the top happens in the root/Window context, so window.length
should be 10
, hence the 10
in the console from the first function call.
Because arguments
is not an array but is actually an Object of type Arguments
, calling arguments[0]()
means that the this
context of the function call will be of the parent Object, so this.length
is equivalent to arguments.length
, hence the 2
(since there are 2 arguments). (See @Travis J's answer for a more thorough explanation of this part.)
If you were to add
this.fn = fn;
this.fn();
to the method()
function, the result would be 5
.
No comments:
Post a Comment