Friday, 2 June 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

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...