«Любой из метасимволов
!"#$%&'()*+,./:;<=>?@[\]^`{|}~
как буквальная часть имени, он должен быть экранирован с двумя обратными косыми чертами: \\
.
Например , элемент с id = "foo.bar", может использовать селектор
$("#foo\\.bar")
"[источник: jquery doc ], а элемент с id =" foo [ bar] "(даже если он недействителен для W3C, но распознан JQuery), можно использовать селектор
$("#foo\\[bar\\]")
(Только один asnwer, как и многие другие, но все вместе:))
Да, object.watch
(хотя это нестандартно). Вот моя реализация , которая работает во всех основных браузерах.
Не напрямую: вам нужен парный геттер / сеттер с каким-то интерфейсом "addListener / removeListener" ... или плагин NPAPI (но это совсем другая история).
Нет.
Но, если это действительно так важно, у вас есть 2 варианта (первый проверяется, второй - нет):
Во-первых, используйте сеттеры и геттеры, например :
var myobj = {a : 1};
function create_gets_sets(obj) { // make this a framework/global function
var proxy = {}
for ( var i in obj ) {
if (obj.hasOwnProperty(i)) {
var k = i;
proxy["set_"+i] = function (val) { this[k] = val; };
proxy["get_"+i] = function () { return this[k]; };
}
}
for (var i in proxy) {
if (proxy.hasOwnProperty(i)) {
obj[i] = proxy[i];
}
}
}
create_gets_sets(myobj);
тогда вы можете сделать что-то вроде:
function listen_to(obj, prop, handler) {
var current_setter = obj["set_" + prop];
var old_val = obj["get_" + prop]();
obj["set_" + prop] = function(val) { current_setter.apply(obj, [old_val, val]); handler(val));
}
затем установить слушателя как:
listen_to(myobj, "a", function(oldval, newval) {
alert("old : " + oldval + " new : " + newval);
}
Во-вторых, я действительно забыл, я отправлю, пока думаю об этом :)
EDIT: О, я помню: ) Вы можете навести часы на значение:
Учитывая myobj выше, с буквой «a» на нем:
function watch(obj, prop, handler) { // make this a framework/global function
var currval = obj[prop];
function callback() {
if (obj[prop] != currval) {
var temp = currval;
currval = obj[prop];
handler(temp, currval);
}
}
return callback;
}
var myhandler = function (oldval, newval) {
//do something
};
var intervalH = setInterval(watch(myobj, "a", myhandler), 100);
myobj.set_a(2);
Как ответ Люка Шафера ( примечание : это относится к его исходному сообщению; но весь смысл здесь остается в силе после редактирования), я бы также предложите пару методов 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
};
})();
Теперь вы можете использовать тот же метод для создания и добавления слушателей, как предложил Люк, но вы можете быть уверены, что невозможно прочитать или записать в
, оставаясь незамеченным!
Все еще на пути Люка, я предлагаю простой способ добавить инкапсулированные поля полей и соответствующих методов получения / установки объектов с помощью простого вызова функции.
Обратите внимание, что это будет правильно работать только с типами значений . Чтобы это работало с ссылочными типами , должна быть реализована какая-то глубокая копия (см., Например, этот ).
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);