Istnieje wzorzec, który jest często nazywany "Delegatem", który rozwiązuje ten problem.
w JavaScript, nie-zbyt fantazyjne realizacja może wyglądać mniej więcej tak:
/** 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(); }
}
W przykładzie będzie go używać tak:
this.b = function() {
Z(Delegate.create(this, this.c));
}
można również napisać funkcje którzy oczekują na Delegata:
function Z(d) {
d.invoke();
}
następnie, w A
, twój impl od b
staje:
this.b = function() {
var d = new Delegate(this, this.c);
Z(d);
SomeOtherFunc(d);
}
Delegate
tylko zapewnia prosty i spójny sposób enkapsulacji odniesienie this
(co masz nazwie self
), wewnątrz instancji obiektu, które mogą być uregulowane jak każdy inny instancji obiektu. Jest bardziej czytelny i nie musi zanieczyszczać zakresu funkcji zbytecznymi zmiennymi, takimi jak self
. Mądrzejsza implementacja delegata może mieć własne metody i inny powiązany stan. Możliwe jest również zbudowanie delegata w taki sposób, aby pomógł zminimalizować niektóre problemy związane z zarządzaniem pamięcią (choć kod, który tu pokazałem, zdecydowanie nie jest tego przykładem).
prawo, w tym prostym przykładzie, nie ma powodu do owinięcia. Nie powinno być trudno wymyślić przykład, w którym jest to konieczne. (Zmiana parametrów itp.) Jeśli nie owijasz, zakładam, że zamknięcie zostało zakończone, jak można by się spodziewać? –
bez anonimowego opakowania, 'c' jest wywoływane z niepoprawnym referencją' this'. – Lee
@ Jonathan - Tak, słusznie, w takim przypadku chciałbyś przekazać zmienną w taki sposób, jakbyś miał "ja", który daje ci dostęp do tego, co jest w zamknięciu. –