我不得不在临时变量中保存this
以便在其他函数中访问它。例如,在下面的两种方法中,我将this
保留在that
变量中:
startTimer: function () {
var that = this;
if ($('#defaultCountdown:hidden'))
$('#defaultCountdown').show('slow');
shortly = new Date();
shortly.setSeconds(shortly.getSeconds() + 5);
$('#defaultCountdown').countdown('change', { until: shortly,
layout: '<ul id="errorList"><li>Next update in <b>{snn}</b> {desc}</li></ul>',
description: 'seconds',
onExpiry: function () {
that.performUpdate();
}
});
},
performUpdate: function () {
var that = this;
this.message.fetch({
success: function () {
$('#calleesStatuses').html('');
that.callees.refresh(that.message.get("Callees"));
$('#defaultCountdown').hide('slow');
that.startTimer();
},
error: function (request, settings) {
that.killCountDown();
showErrorMessage(request.responseText)
}
});
},
无论如何还是可以使用apply
吗?
答案 0 :(得分:4)
ECMAScript 5引入了Function.bind()
[docs],因此只有较新的浏览器才支持它。可以在我链接到的文档中找到替代实现。如果您将其包含在代码中,则也可以在其他(较旧的)浏览器中使用bind()
。
它允许您设置函数中应引用的对象this
。所以你可以写:
performUpdate: function () {
this.message.fetch({
success: function () {
$('#calleesStatuses').html('');
this.callees.refresh(this.message.get("Callees"));
$('#defaultCountdown').hide('slow');
this.startTimer();
}.bind(this),
error: function (request, settings) {
this.killCountDown();
showErrorMessage(request.responseText)
}.bind(this)
});
},
答案 1 :(得分:1)
不,没有。 this
的值在闭包中将不同于闭包定义的范围,因此唯一的方法是使它更清洁是在对象级别定义它,所以至少你只需要为每个对象做一次,看起来你已经在做了。
编辑:
找出“不存在”,因为bind
是一种有效的替代方案,并且存在可比性实施(参见其他答案)。虽然我个人认为var self = this;
更清洁,你只需要为每个对象定义一次,但这是一个偏好的问题。
答案 2 :(得分:1)
我认为这是最简单的方法。这就是我所做的(尽管我正在编写GWT代码),以引用内部匿名函数中的包装函数的this
。
即使像this.wrappingMethod.this
这样的东西是可能的,将this
存储在根据您的口味命名的变量中也更具可读性(您可以使用更具描述性的名称,当然),并且(仍假设你以某种方式冷引用包装范围)它会更强大,因为你可以引入另一个级别而不必重写所有引用。
答案 3 :(得分:0)
我想这并不舒服,但如果原始this
是您可以执行startTimer
和killCountdown
等功能的唯一上下文,那就不是真的了。我建议给它一个更有意义的名字,比如timer
或其他什么。实际上,this
只是一个方便的关键字,用于引用我们正在执行的任何内容的所有者,并且应该随着所有者的更改而更改。如果“this / that”变得难以阅读,解决方案是将名称从that
更改为更具语义意义的名称。
答案 4 :(得分:0)
您所做的是JavaScript中的标准模式,但使用self
代替that
是传统的模式。但您可以使用bind()
方法,如下所示:
onExpiry: performUpdate.bind(this);
如果您正在使用扩展Function
原型的框架来包含它,或者您的Javascript解释器已经足够了。 (bind
在幕后创建了相同类型的匿名函数,但由于它必须处理各种特殊情况,因此可能效率较低。)