Extend your code a bit:
var length = 20; function fn() { console.log(this, this.length); } var o = { length: 10, e: function(fn) { fn(); fn.call(this); arguments[0](); } } oe(fn);β
Demo: http://jsfiddle.net/ambiguous/Ckf2b/
Now we can see that this (and therefore where this.length comes this.length ) when fn is called. This gives me the following result:
DOMWindow 0 Object 10 [function fn() { console.log(this, this.length); }] 1
We also have three ways to call the fn function:
fn() : just call it like any old function.fn.call(this) : use call to create a specific context (AKA this ).arguments[0]() : call fn through the arguments object.
When you say fn() , the explicit value of this not displayed anywhere, so in the browser you get a window like your this . The global window has a length property:
Returns the number of frames (frames or iframes) in a window.
That when zero comes (in my output), your window.length may be different.
We call e as oe(fn) , so this inside e is o , which means oe(...) (banning related functions and related complexities). Thus, this in fn.call(this) is equal to o and makes fn.call(this) the same (more or less) as o.fn = fn; o.fn() o.fn = fn; o.fn() , and we get o and 10 in the console. Notice that the dot is displayed again?
fn.call(o) is similar to o.fn = fn; o.fn() o.fn = fn; o.fn()
The third, arguments[0]() , contains a hidden dot because p = 'm'; o[p] p = 'm'; o[p] (more or less) matches om , so arguments[0]() is like fn = arguments[0]; arguments.fn = fn; arguments.fn() fn = arguments[0]; arguments.fn = fn; arguments.fn() fn = arguments[0]; arguments.fn = fn; arguments.fn() .