Как ответ Люка Шефера ( примечание : это относится к его оригинальному сообщению; но весь смысл здесь остается в силе после редактирования ), я бы также предложите пару методов Get / Set для доступа к вашему значению.
Однако я бы предложил некоторые модификации (и именно поэтому я публикую ...).
Проблема с этим кодом заключается в том, что поле a
объекта myobj
является непосредственно доступным, поэтому можно получить к нему доступ или изменить его значение, не вызывая слушателей:
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!
Инкапсуляция
Итак, чтобы гарантировать, что слушатели действительно вызваны, мы должны запретить прямой доступ к полю a
. Как это сделать? Используйте закрытие !
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
};
})();
Теперь вы можете использовать тот же метод для создания и добавления слушателей, как предложил Люк, но вы можете быть уверены, что нет никакого способа читать или писать в a
, оставаясь незамеченным!
Добавление инкапсулированных полей программно
По-прежнему на пути Люка, я предлагаю теперь простой способ добавления инкапсулированных полей и соответствующих методов получения / установки к объектам с помощью простого вызова функции.
Обратите внимание, что это будет правильно работать только с типами значений . Чтобы это работало с ссылочными типами , необходимо было бы реализовать какую-то глубокую копию (см., Например, этот ).
function addProperty(obj, name, initial) {
var field = initial;
obj["get_" + name] = function() { return field; }
obj["set_" + name] = function(val) { field = val; }
}
Это работает так же, как и раньше: мы создаем локальную переменную для функции, а затем создаем замыкание.
Как это использовать? Простой:
var myobj = {};
addProperty(myobj, "total", 0);
window.alert(myobj.get_total() == 0);
myobj.set_total(10);
window.alert(myobj.get_total() == 10);