Hay un patrón que a menudo se denomina "Delegar", que soluciona este problema.
en JavaScript, una aplicación no muy elegante podría ser algo como esto:
/** class Delegate **/
var Delegate = function(thisRef, funcRef, argsArray) {
this.thisRef=thisRef;
this.funcRef=funcRef;
this.argsArray=argsArray;
}
Delegate.prototype.invoke = function() {
this.funcRef.apply(this.thisRef, this.argsArray);
}
/** static function Delegate.create - convenience function **/
Delegate.create = function(thisRef, funcRef, argsArray) {
var d = new Delegate(thisRef, funcRef, argsArray);
return function() { d.invoke(); }
}
En su ejemplo, se usaría así:
this.b = function() {
Z(Delegate.create(this, this.c));
}
también se puede escribir funciones que esperan recibir un Delegado:
function Z(d) {
d.invoke();
}
luego, en A
, su impl de b
se convierte en:
this.b = function() {
var d = new Delegate(this, this.c);
Z(d);
SomeOtherFunc(d);
}
El Delegate
simplemente proporciona una manera simple y consistente de encapsular la referencia this
(que usted ha llamado self
), dentro de una instancia de objeto que puede ser tratada como cualquier otra instancia de objeto. Es más legible y evita tener que contaminar el alcance de su función con variables superfluas como self
. Una implementación delegada más elegante podría tener sus propios métodos y otro estado relacionado. También es posible construir el delegado de tal manera que ayude a minimizar algunos problemas de administración de memoria relacionados con el alcance (aunque el código que he mostrado aquí definitivamente no es un ejemplo de eso).
derecho, en este ejemplo sencillo, no hay ninguna razón por la envoltura. No debería ser difícil concebir un ejemplo donde sea necesario. (Cambiando parámetros, etc.) Sin embargo, si no se ajusta, ¿supongo que el cierre se pasa como uno podría esperar? –
sin el contenedor anónimo, se llama 'c' con la referencia' this' incorrecta. – Lee
@Jonathan - Sí, correcto, en ese caso, querrá pasar una variable tal como usted tiene 'self' que le permite acceder a lo que está en el cierre. –