Ответ 1
(Извините за перекрестную рассылку, но этот ответ, который я дал подобному вопросу, прекрасно работает здесь)
Я создал небольшую object.watch shim для этого некоторое время назад. Он работает в IE8, Safari, Chrome, Firefox, Opera и т.д.
Обратите внимание, что Object.Watch
и Object.Observe
как сейчас (по состоянию на июнь 2018 года).
Я искал простой способ отслеживать объект или переменную на предмет изменений и обнаружил Object.watch()
, который поддерживается в браузерах Mozilla, но не в IE. Поэтому я начал искать, чтобы увидеть, если кто-то написал какой-то эквивалент.
Единственной вещью, которую я нашел, был плагин jQuery, но я не уверен, что это лучший путь. Я, конечно, использую jQuery в большинстве своих проектов, поэтому меня не беспокоит аспект jQuery...
В любом случае, вопрос: кто-то может показать мне рабочий пример этого плагина jQuery? У меня проблемы с этим...
Или кто-нибудь знает какие-либо лучшие альтернативы, которые будут работать кросс-браузер?
Обновление после ответов:
Спасибо всем за ответы! Я опробовал код, размещенный здесь: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html
Но я не мог заставить его работать с IE. Приведенный ниже код отлично работает в Firefox, но ничего не делает в IE. В Firefox каждый раз, watcher.status
изменяется watcher.status
вызывается document.write()
в watcher.watch()
и вы можете увидеть результат на странице. В IE этого не происходит, но я вижу, что watcher.status
обновляет значение, потому что последний вызов document.write()
показывает правильное значение (как в IE, так и в FF). Но если функция обратного вызова не вызывается, то это бессмысленно... :)
Я что-то пропустил?
var options = {'status': 'no status'},
watcher = createWatcher(options);
watcher.watch("status", function(prop, oldValue, newValue) {
document.write("old: " + oldValue + ", new: " + newValue + "<br>");
return newValue;
});
watcher.status = 'asdf';
watcher.status = '1234';
document.write(watcher.status + "<br>");
(Извините за перекрестную рассылку, но этот ответ, который я дал подобному вопросу, прекрасно работает здесь)
Я создал небольшую object.watch shim для этого некоторое время назад. Он работает в IE8, Safari, Chrome, Firefox, Opera и т.д.
Этот плагин просто использует таймер/интервал для повторной проверки изменений на объекте. Может быть, достаточно хорошо, но лично я хотел бы получить более непосредственную информацию в качестве наблюдателя.
Здесь попытка принести watch
/unwatch
в IE: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html.
Он меняет синтаксис на Firefox, добавляя наблюдателей. Вместо:
var obj = {foo:'bar'};
obj.watch('foo', fooChanged);
Вы делаете:
var obj = {foo:'bar'};
var watcher = createWatcher(obj);
watcher.watch('foo', fooChanged);
Не так сладко, но в качестве наблюдателя вы незамедлительно уведомлены.
Ответы на этот вопрос немного устарели. Object.watch и Object.observe устарели и не должны использоваться.
Сегодня вы можете использовать объект Proxy для отслеживания (и перехвата) изменений, внесенных в объект. Вот основной пример:
var targetObj = {};
var targetProxy = new Proxy(targetObj, {
set: function (target, key, value) {
console.log('${key} set to ${value}');
target[key] = value;
}
});
targetProxy.hello_world = "test"; // console: 'hello_world set to test'
Если вам нужно наблюдать за изменениями, внесенными во вложенный объект, вам нужно использовать специализированную библиотеку. Я опубликовал Observable Slim, и он работает следующим образом:
var test = {testing:{}};
var p = ObservableSlim.create(test, true, function(changes) {
console.log(JSON.stringify(changes));
});
p.testing.blah = 42; // console: [{"type":"add","target":{"blah":42},"property":"blah","newValue":42,"currentPath":"testing.blah",jsonPointer:"/testing/blah","proxy":{"blah":42}}]
Текущий ответ
Используйте новый объект Proxy, который может наблюдать за изменениями в его цели.
let validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer');
}
if (value > 200) {
throw new RangeError('The age seems invalid');
}
}
// The default behavior to store the value
obj[prop] = value;
// Indicate success
return true;
}
};
let person = new Proxy({}, validator);
person.age = 100;
console.log(person.age); // 100
person.age = 'young'; // Throws an exception
person.age = 300; // Throws an exception
Старый ответ от 2015
Вы могли бы использовать Object.observe() из ES7. Здесь полифилл. Но Object.observe() теперь отменен. Извините люди!
Обратите внимание, что в Chrome 36 и выше вы можете использовать Object.observe
. На самом деле это часть будущего стандарта ECMAScript, а не специфичная для браузера функция, такая как Mozilla Object.watch
.
Object.observe
работает только с объектами, но намного более эффективен, чем Object.watch
(который предназначен для целей отладки, а не для использования в производстве).
var options = {};
Object.observe(options, function(changes) {
console.log(changes);
});
options.foo = 'bar';
вы можете использовать Object.defineProperty.
посмотреть свойство bar
в foo
Object.defineProperty(foo, "bar", {
get: function (val){
//some code to watch the getter function
},
set: function (val) {
//some code to watch the setter function
}
})
Я нашел двух человек, которые утверждают, что решили эту проблему:
Просмотр объектов Crossbrowser (поддержка утверждений для IE, Opera, Safari)
watch() Отсутствует функция JS в IE с использованием prototype.js для IE (? Opera, Safari?)
Я использовал Watch.js в одном из моих проектов. И это работает нормально. Одним из основных преимуществ использования этой библиотеки является:
"С Watch.JS вам не придется менять способ развития".
Пример приведен ниже
//defining our object however we like
var ex1 = {
attr1: "initial value of attr1",
attr2: "initial value of attr2"
};
//defining a 'watcher' for an attribute
watch(ex1, "attr1", function(){
alert("attr1 changed!");
});
//when changing the attribute its watcher will be invoked
ex1.attr1 = "other value";
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src/watch.min.js"></script>
Я также считаю, что сейчас самое лучшее решение - использовать Watch.JS, найти хороший учебник здесь: Слушать/Следить за изменениями объектов или массивов в Javascript (Измененное событие свойства на объектах Javascript)