4

我的代码是:

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

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

o.e(fn);

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

4

2 回答 2

6

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成为 object o,你可以先使用callor apply,或bindobject 。

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);
于 2012-09-03T03:43:04.883 回答
2

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

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/

现在我们可以看到调用时是什么this(以及从何this.length而来) 。fn这给了我以下输出:

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

我们也有三种调用函数的方式fn

  1. fn(): 就像任何旧函数一样调用它。
  2. fn.call(this)call用于强制特定上下文(AKA this)。
  3. arguments[0]():fn通过arguments对象调用。

当您说. fn()_ 全局恰好有一个属性thiswindowthiswindowlength

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

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

我们在里面这么称呼eis ,o.e(fn)这就是意思(除了绑定函数和相关的复杂性)。所以in is and that与我们在控制台中得到的and相同(或多或少) 。注意到那个点再次出现了吗?thiseoo.e(...)thisfn.call(this)ofn.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()

于 2012-09-03T04:09:01.520 回答