为什么此函数附加到全局上下文

时间:2013-06-16 12:43:47

标签: javascript this global

当我使用var关键字声明任何变量时,它会在封闭范围内声明。但是在下面的代码中,我已使用c关键字声明了函数a.b(在对象方法var内),并且函数this内的c仍被绑定到全局对象window。这是为什么?

var a = {
        b: function () {
            var c = function () {
                return this;
            };
            return c();
        }
    };

document.write(a.b());  //prints: [object Window]

2 个答案:

答案 0 :(得分:3)

this的值由上下文决定,而不是范围。

当您在没有任何上下文(context.func())的情况下调用函数时(c()),默认上下文是默认对象(在浏览器中为window),除非您处于严格模式(在这种情况下,它是undefined)。

(此规则有例外情况,例如applycallbindnew,但这些都不适用于此处。)

答案 1 :(得分:1)

许多人对感到困惑。值取决于4种调用方法之一 但是,功能调用会导致大部分混淆 如果函数是对象的成员,则是对象本身。

obj.someFunction(); //method invocation

如果在没有上下文的情况下调用函数,则全局对象(在'严格模式'中未定义。)

someFunction();  //functional invocation

在对象中调用函数时会发生混淆,但不会像anObject.testWithHelper(..)中那样作为对象的成员发生混淆;

var testForThis = function(isThis, message) {
    //this can be confusing
    if(this === isThis) 
        console.log("this is " + message);
    else
        console.log("this is NOT " + message);    
};  

//functional invocation
testForThis(this, "global"); //this is global

var anObject = {
    test: testForThis, //I am a method
    testWithHelper: function(isThis, message) {
        //functional invocation
        testForThis(isThis, message + " from helper");
    }
};

//method invocation
anObject.test(anObject, "anObject"); //this is anObject
//method invocation followed by functional invocation
anObject.testWithHelper(anObject, "an object"); //this is NOT anObject from helper

这是我的JSFIDDLE

如果您希望c返回a,可以使用

var a = {
    b: function () {
        var that = this;
        var c = function () {
            return that;
        };
        return c();
    }
};

或者一起避免这一切:

var getNewA = function() {
    var newA = {};
    newA.b = function() {
        var c = function() {
            return newA;
        };
        return c();
    };    
    return newA;
};

var newA = getNewA();