why the code this point to window object?

孤街浪徒 提交于 2019-12-01 06:49:39

When the this keyword occurs inside a function, its value depends on how the function is called.

In your case, fn() is called without providing the a this value, so the default value is window. With arguments[0](), the context is the arguments object, whose length is 1.

The point is it does not matter where the function is called, but it matters how the function is called.

var length = 20;
function fn(){
    console.log(this.length);
}

var o = {
    length:10,
    e:function (fn){
       fn(); // this will be the window.
       arguments[0](); // this will be arguments object.
    }
}

o.e(fn);

Further more, if you want this to be the object o, you could use call or apply, or bind an object first.

var length = 20;
function fn(){
    console.log(this.length);
}

var o = {
    length:10,
    e:function (fn){
       var fn2 = fn.bind(this);
       fn.call(this); // this in fn will be the object o.
       fn.apply(this); // this in fn will be the object o.
       fn2(); // this also will be the object o.
    }
}

o.e(fn);

Let's expand your code a little bit:

var length = 20;
function fn() {
    console.log(this, this.length);
}

var o = {
    length: 10,
    e: function(fn) {
        fn();
        fn.call(this);
        arguments[0]();
    }
}

o.e(fn);​

Demo: http://jsfiddle.net/ambiguous/Ckf2b/

Now we can see what this is (and thus where this.length comes from) when fn is called. This gives me the following output:

DOMWindow 0
Object 10
[function fn() { console.log(this, this.length); }] 1

We also have three ways of calling the function fn:

  1. fn(): just call it like any old function.
  2. fn.call(this): Use call to force a specific context (AKA this).
  3. arguments[0](): Call fn through the arguments object.

When you say fn(), there is no explicit value of this anywhere in sight so, in a browser, you get window as your this. The global window happens to have a length property:

Returns the number of frames (either frame or iframe elements) in the window.

That's where the zero (in my output) comes from, your window.length may be different.

We call e as o.e(fn) so this inside e is o, that's what o.e(...) means (barring bound functions and related complexities). So the this in fn.call(this) is o and that makes fn.call(this) the same (more or less) as o.fn = fn; o.fn() and we get o and 10 in the console. Notice that dot showing up again?

fn.call(o) is like o.fn = fn; o.fn()

The third one, arguments[0](), contains a hidden dot as p = 'm'; o[p] is (more or less) the same as o.m so arguments[0]() is like fn = arguments[0]; arguments.fn = fn; arguments.fn().

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!