Tuesday, 3 October 2017

Why this behavior for javascript code?




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

casting - Why wasn't Tobey Maguire in The Amazing Spider-Man? - Movies & TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...