我有以下Javascript对象:
function Alfa() {
this.status='';
this.setStatus = function(value) {
this.status=value
}
}
function Beta() {
this.setSomething = function(setter) {
setter('Something');
}
}
而不是执行:
alf=new Alfa();
alf.setStatus('foo');
这很好,如果您查看 alf 的值,状态设置为'foo',但是:
bet=new Beta();
bet.setSomething(a.setStatus);
我所期待的是下注将执行 alf 的 setStatus 功能,并将 status 值设置为'然而,事情并没有发生。 alf 的 setStatus 已执行,但这不是指向 alf 实例,而是指向 Window ,因此属性状态为设置 Window 而不是 alf 。
获得所需功能的正确方法是什么?
这当然是简化的实现,在现实生活中我想将 alf 的那些函数传递给事件处理程序,因此我无法更改 Beta 实现,例如:
$('xxx').click(alf.setStatus)
答案 0 :(得分:4)
JavaScript函数未绑定。这意味着this
取决于它的调用方式而不是它的定义方式。因为您是在bet
内调用该方法,所以this
是bet
要解决此问题,您需要创建一个绑定函数,无论函数如何被调用,都会创建一个稳定的this
。
如果您使用的是兼容ES5的JavaScript解释器,则可以使用:Function.bind
alf.setStatus.bind(alf)
或者,如果你不是有几个es5垫片在旧的解释器中提供此功能。事实上,在mdn引用上提供了一个bind。 JQuery有一个名为$.proxy
一个简单的实现是你需要一个带有函数和范围的函数。然后专门在该范围内调用您的方法,而不是使用它。就像是。
function bind(func,o) { return function() { func.call(o); } }
答案 1 :(得分:1)
JavaScript中的函数没有附加上下文,例如Python中的绑定方法。所以你可以做的是用上下文调用setStatus函数,如下所示:
bet.setSomething(function(value) {
a.setStatus.call(a, value);
});
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call
答案 2 :(得分:1)
将setter('Something');
更改为setter.call(this, 'Something');
将有效。
答案 3 :(得分:1)
function Alfa() {
this.status='';
this.setStatus = function(value) {
this.status=value
}
}
function Beta() {
this.status='';
this.setSomething = function(setter) {
setter.call(this,'Something');
}
}