Jako odpowiedź Luke'a Schafera ( uwaga : odnosi się to do jego oryginalnego postu, ale cały punkt tutaj pozostaje ważny po edycji ), sugerowałbym również parę metod Get / Set, aby uzyskać dostęp do twojej wartości.
Sugerowałbym jednak pewne modyfikacje (i dlatego publikuję ...).
Problem z tym kodem polega na tym, że pole a
obiektu myobj
jest bezpośrednio dostępne, więc można uzyskać do niego dostęp / zmienić jego wartość bez wyzwalania detektorów:
var myobj = { a : 5, get_a : function() { return this.a;}, set_a : function(val) { this.a = val; }}
/* add listeners ... */
myobj.a = 10; // no listeners called!
Kapsułkowanie
Tak więc, aby zagwarantować, że słuchacze są faktycznie wezwani, musielibyśmy zabronić tego bezpośredniego dostępu do pola a
. Jak to zrobić? Użyj zamknięcia !
var myobj = (function() { // Anonymous function to create scope.
var a = 5; // 'a' is local to this function
// and cannot be directly accessed from outside
// this anonymous function's scope
return {
get_a : function() { return a; }, // These functions are closures:
set_a : function(val) { a = val; } // they keep reference to
// something ('a') that was on scope
// where they were defined
};
})();
Teraz możesz użyć tej samej metody do tworzenia i dodawania słuchaczy, jak zaproponował Luke, ale możesz być pewny, że nie ma możliwości, aby czytać i pisać a
niezauważone!
Programowe dodawanie pól enkapsulowanych
Wciąż podążając śladem Luke'a, proponuję teraz prosty sposób dodawania do obiektów zamkniętych pól i odpowiednich modułów pobierających / ustawiających za pomocą prostego wywołania funkcji.
Pamiętaj, że będzie to działać poprawnie tylko z typami wartości . W tym celu do pracy z typami referencyjnymi , jakiś głęboki kopii musiałyby być realizowane (patrz ten jeden , na przykład).
function addProperty(obj, name, initial) {
var field = initial;
obj["get_" + name] = function() { return field; }
obj["set_" + name] = function(val) { field = val; }
}
Działa to tak samo jak poprzednio: tworzymy zmienną lokalną na funkcji, a następnie tworzymy zamknięcie.
Jak tego użyć? Prosty:
var myobj = {};
addProperty(myobj, "total", 0);
window.alert(myobj.get_total() == 0);
myobj.set_total(10);
window.alert(myobj.get_total() == 10);