JavaScript中的函数调用模式作用域规则

soj*_*jin 6 javascript

这是一个来自"Javascript - The Good Parts"的工作示例.

function add(x, y){ return x + y};

var myObject = {
    value: 0,
    increment: function (inc) {
        this.value += typeof inc === 'number' ? inc : 1;
    }
};

myObject.increment(2);
document.writeln(myObject.value); 

myObject.double = function (  ) {
    var that = this;    // Workaround.

    var helper = function (  ) {
        that.value = add(that.value, that.value)
    };

    helper(  );    // Invoke helper as a function.
};

myObject.double(  );
document.writeln(myObject.value);    // 4
Run Code Online (Sandbox Code Playgroud)

对于函数调用模式,'this'对象将具有全局引用.但我不能完全理解所提到的解决方案的引擎盖: -

var that = this;    // Workaround.
Run Code Online (Sandbox Code Playgroud)

如果我们这样做,我们不是只是将'this'的引用复制到'that'吗?即'that'将与'this'一样保持全球范围?这在内部如何运作?

Nic*_*ver 10

它在这里不一样,this指的是myObject你得到value它拥有的正确属性,this会引用window...这就是为什么你要像它一样保持引用的原因.

你可以在这里测试一下,helper功能里面的一些警告显示发生了什么.

另一种选择是具有正确上下文的函数.call().apply()函数,因此this继续引用myObject您想要的实例...像这样:

myObject.double = function () {
    var helper = function () {
        this.value = add(this.value, this.value)
    };
    helper.call(this);    // Invoke helper as a function.
};
Run Code Online (Sandbox Code Playgroud)

你可以在这里测试那个版本.


And*_*rea 2

这里涉及到两个函数:一个是myObject.double,另一个是helper。当你打电话时,myObject.double()这是指myObject。所以that === myObject。稍后,在该函数内,您还调用helper(),并且在该范围内您有this === the global object