为什么代码会指向window对象

why the code this point to window object?

本文关键字:window 对象 代码 为什么      更新时间:2023-09-26

我的代码是:

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

输出是20,1,谁能告诉我为什么?

this关键字出现在函数内部时,其值取决于函数的调用方式。

在您的情况下,调用fn()时没有提供this值,因此默认值为window。对于arguments[0](),上下文是arguments对象,其长度为1

关键是函数在哪里调用并不重要,重要的是函数如何调用。

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);

此外,如果希望this为对象o,则可以先使用callapply,或bind作为对象。

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);

让我们稍微扩展一下您的代码:

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);​

演示:http://jsfiddle.net/ambiguous/Ckf2b/

现在我们可以看到当调用fnthis是什么(以及this.length来自哪里)。这给了我以下输出:

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

我们还有三种方法可以调用函数fn:

  1. fn():就像调用任何旧函数一样
  2. fn.call(this):使用call强制创建特定上下文(也称为this
  3. arguments[0]():通过arguments对象调用fn

当你说fn()时,在任何地方都看不到this的显式值,所以在浏览器中,你会得到window作为你的this。全局window恰好具有length属性:

返回窗口中的帧数(frame或iframe元素)。

这就是零(在我的输出中)的来源,你的window.length可能不同。

我们把e称为o.e(fn),所以e中的this就是o,这就是o.e(...)的意思(除了有界函数和相关的复杂性)。所以fn.call(this)中的thiso,这使得fn.call(this)o.fn = fn; o.fn()相同(或多或少),我们在控制台中获得o10。注意到那个点又出现了吗?

fn.call(o)类似于o.fn = fn; o.fn()

第三个,arguments[0](),包含一个隐藏点,因为p = 'm'; o[p](或多或少)与o.m相同,所以arguments[0]()类似于fn = arguments[0]; arguments.fn = fn; arguments.fn()