JavaScript:在调用之前将函数重新分配给局部变量而不是直接调用,以及对'this'的后续影响

时间:2015-03-04 18:01:57

标签: javascript

考虑这个例子:

function Dummy(buddy) {
    this._buddy = buddy;
}
Dummy.prototype.greetBuddy = function() {
    console.log('Hello, '+this._buddy);
}

function outerGreet1(dummy) {
    var func = dummy.greetBuddy;
    func();
}
function outerGreet2(dummy) {
    dummy.greetBuddy();
}

我只想说这不能说明我为什么要这样做,但这是我所遇到的基本的升华。我刚刚修复了我的程序中由于这种区别而产生的错误。 outerGreet1会抛出一个错误,因为它找不到this._buddy,而outerGreet2会打印出预期的结果。

我只是将函数复制到局部变量以获得代码清晰度,但显然这对我来说是一个成熟的学习体验。到底发生了什么?我猜这个'最终指的是outerGreet1函数?我来自Java所以我理解JavaScript只有函数范围,但为什么创建一个新的函数引用会改变它的行为?我的印象是“这个'对应当前的范围,我不确定重新分配如何改变范围,所以我的理解在某处有缺陷。

道歉,如果这是一个常见的JavaScript问题,但我很难以一种能够找到答案的方式来表达我的搜索。

1 个答案:

答案 0 :(得分:0)

this变量取决于函数的使用方式。

如果您实例化该函数(将其视为类),那么this将引用该类的实例:

new outerGreet1(dummy); // `this` is an instance of outerGreet1

如果您使用Function.prototype.call进行调用,则this会引用您传递给call方法的任何对象:

outerGreet1.call(anotherObjec, dummy); // `this` refers to anotherObject

如果你直接执行它,那么this可能会引用窗口或其他任何周围范围。

outerGreet1(dummy); // `this` likely refers to the window object

你也可以使用Function.prototype.bind将你的功能包装在一个特定的范围内,以帮助清理:

var wrappedExample = outerGreet1.bind(aSpecificObject);
wrappedExample(dummy); // Doesn't matter how it's called, `this` will refer to aSpecificObject

当然,您可能需要在使用bind之前考虑目标浏览器(或使用polyfill)。