原因相当微妙:this
在 JavaScript 中完全取决于函数的调用方式。要在调用this
to 期间设置为,您必须在从对象中检索到它时立即调用,如下所示:car
getName
getName
car
car.getName() // or
car["getName"]()
(或者通过Function#call
or Function#apply
,它可以让你this
明确地指定值。)
您在示例中所做的实际上是这样的:
// Set f to the result of the assignment expression,
// which is a reference to the getName function
var f = (car.getName = car.getName);
// Call it (separately)
f();
...这是不同的。以这种方式调用的函数被this
设置为全局对象(window
浏览器中的 , )。(在严格模式下除外;在严格模式下this
将是undefined
。)
更多(来自我贫血的博客):
它是否存在一种机制(使用变量或其他)来关注对象函数的非重新分配,以便如果发生这种情况,这种机制会像往常一样阻止 this 关键字的分配(等于等于物体)?
我不完全确定我是否遵循这个问题,但是如果您想要一个始终具有预设this
值的函数,那么是的,有几种方法可以做到这一点。
一种是使用新的 ES5 功能bind
:
var name = "Jaguar";
var car = {
name: "Ferrari"
};
car.getName = function(){
return this.name;
}.bind(car);
alert((car.getName = car.getName)()); // "Ferrari"
bind
返回一个始终this
设置为您给它的参数的函数。
另一种方法是使用闭包。事实上,你可以bind
很容易地在 ES3 中创建一个 -like 函数:
function pseudoBind(func, thisArg) {
return function() {
return func.apply(thisArg, arguments);
};
}
这并不能做所有事情bind
,但它确实起到了this
作用。然后你会有:
var name = "Jaguar";
var car = {
name: "Ferrari"
};
car.getName = pseudoBind(function(){
return this.name;
}, car);
alert((car.getName = car.getName)()); // "Ferrari"
更多关于闭包的信息(同样来自博客):
在未来的规范中,我们将获得一种创建具有预设this
值的函数的声明方式(所谓的“箭头函数”,因为它们的语法涉及使用=>
而不是function
关键字)。