为什么代码这个指向window对象?

时间:2012-09-03 03:37:07

标签: javascript arguments this

我的代码是:

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

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

o.e(fn);

输出为20,1,谁可以告诉我原因?

2 个答案:

答案 0 :(得分:6)

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

在您的情况下,调用fn()时不会提供此值,因此默认值为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,则可以先使用callapplybind对象。< / p>

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

答案 1 :(得分: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
  4. 当您说fn()时,this没有任何明确的价值,因此,在浏览器中,您会window作为this。全球window碰巧有length property

      

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

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

    我们将e称为o.e(fn)this e内的oo.e(...),这就是this的含义(禁止约束函数和相关复杂性) )。因此fn.call(this)中的ofn.call(this)o.fn = fn; o.fn()o相同(或多或少),我们得到10和{控制台中的{1}}。注意点再次出现?

      

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