javascript - Pare de segurar 'this' em uma variável temporária
Estou continuamente tendo que manter this em uma variável temporária para poder acessá-lo em outras funções. Por exemplo, nos dois métodos abaixo, estou mantendo this em uma variável 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)
}
});
},
Existe alguma maneira de contornar isso ou eu poderia possivelmente usar apply?
Resposta #1
O ECMAScript 5 introduziu Function.bind()[docs], então ele é suportado apenas por navegadores mais recentes. Uma implementação alternativa pode ser encontrada na documentação que eu linkei. Se você a incluir no seu código, você também pode usar bind() nos outros navegadores (mais antigos).
Isso permite que você defina a que objeto this deve se referir na função. Então você poderia escrever:
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)
});
},
Resposta #2
Acho que essa é a maneira mais simples de fazer isso. É o que eu faço (embora eu esteja escrevendo código GWT), para referenciar o this da função envolvente em uma função anônima interna.
Mesmo que algo como this.wrappingMethod.this fosse possível, armazenar o this em uma variável nomeada de acordo com seu gosto é muito mais legível (você poderia usar um nome mais descritivo, é claro), e (ainda assumindo que você de alguma forma poderia referenciar o escopo envolvente) será mais robusto, pois você poderia introduzir outro nível sem precisar reescrever todas as referências.
