Als Antwort von Luke Schafer ( Hinweis : Dies bezieht sich auf seinen ursprünglichen Beitrag; der ganze Punkt hier bleibt jedoch nach der Bearbeitung gültig ) würde ich auch ein Paar Get / Set-Methoden vorschlagen, um auf Ihren Wert zuzugreifen.
Ich würde jedoch einige Änderungen vorschlagen (und deshalb poste ich ...).
Ein Problem mit diesem Code besteht darin, dass auf das Feld ades Objekts myobjdirekt zugegriffen werden kann, sodass es möglich ist, darauf zuzugreifen / seinen Wert zu ändern, ohne die Listener auszulösen:
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!
Verkapselung
Um sicherzustellen, dass die Zuhörer tatsächlich angerufen werden, müssten wir diesen direkten Zugriff auf das Feld verbieten a. Wie geht das? Verwenden Sie einen Verschluss !
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
};
})();
Jetzt können Sie die Listener auf dieselbe Weise erstellen und hinzufügen, wie von Luke vorgeschlagen, aber Sie können sicher sein, dass es keine Möglichkeit gibt a, unbemerkt zu lesen oder zu schreiben !
Programmiertes Hinzufügen gekapselter Felder
Immer noch auf Lukes Spur, schlage ich jetzt eine einfache Möglichkeit vor, gekapselte Felder und die entsprechenden Getter / Setter mithilfe eines einfachen Funktionsaufrufs zu Objekten hinzuzufügen.
Beachten Sie, dass dies nur dann richtig funktionieren mit Werttypen . Damit dies funktioniert mit Referenztypen , eine Art tiefer Kopie müßte (siehe implementiert diese ein , zum Beispiel).
function addProperty(obj, name, initial) {
var field = initial;
obj["get_" + name] = function() { return field; }
obj["set_" + name] = function(val) { field = val; }
}
Dies funktioniert genauso wie zuvor: Wir erstellen eine lokale Variable für eine Funktion und anschließend einen Abschluss.
Wie benutzt man es? Einfach:
var myobj = {};
addProperty(myobj, "total", 0);
window.alert(myobj.get_total() == 0);
myobj.set_total(10);
window.alert(myobj.get_total() == 10);