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 a
des Objekts myobj
direkt 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);