所有浏览器的 Object.watch() ?

请注意,Object.WatchObject.Observe现在都不推荐使用(截至2018年6月)。


我一直在寻找一种简单的方法来监视对象或变量的变化,我发现了 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.watch()中的 document.write(),您可以在页面上看到输出。在 IE 中,这种情况不会发生,但是我可以看到 watcher.status正在更新这个值,因为最后一个 document.write()调用显示了正确的值(在 IE 和 FF 中)。但是,如果没有调用回调函数,那么... :)就没有意义了

Am I missing something?

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>");
105140 次浏览

这个插件只是使用一个计时器/间隔来重复检查对象的更改。也许足够好,但我个人希望作为一个观察员更直接。

这里有一个尝试把 watch/unwatch带到 IE: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html

It does change the syntax from the Firefox way of adding observers. Instead of :

var obj = {foo:'bar'};
obj.watch('foo', fooChanged);

你可以:

var obj = {foo:'bar'};
var watcher = createWatcher(obj);
watcher.watch('foo', fooChanged);

没那么甜蜜,但作为一个观察者,你会立刻得到通知。

(很抱歉交叉发帖,但我对类似问题的回答在这里很有效)

我已经为此创建了一个小的 目标,看着他,它可以在 IE8、 Safari、 Chrome、 Firefox、 Opera 等浏览器中运行。

当前答案

使用新的 代理对象,它可以观察目标的更改。

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

Old answer from 2015

你可以用 从 ES7观察()Here's a polyfill.但是 Object.Observer ()现在被取消。对不起人们!

我还认为目前最好的解决方案是使用 Watch.JS,在这里找到一个不错的教程: 监听/监视 Javascript 中的对象或数组更改(Javascript 对象上的属性更改事件)

注意,在 Chrome36或更高版本中,你也可以使用 Object.observe。这实际上是未来 ECMAScript 标准的一部分,而不是像 Mozilla 的 Object.watch那样是浏览器特有的特性。

Object.observe only works on object properties, but is a lot more performant than Object.watch (which is meant for debugging purposes, not production use).

var options = {};


Object.observe(options, function(changes) {
console.log(changes);
});


options.foo = 'bar';

你可以使用 Object.defeProperty

观看 foo中的属性 bar

Object.defineProperty(foo, "bar", {
get: function (val){
//some code to watch the getter function
},


set: function (val) {
//some code to watch the setter function
}
})

这个问题的答案有点过时了。 Object.watch目标,观察都已经过时了,不应该使用。

现在,您可以使用 代理对象来监视(并拦截)对对象所做的更改。下面是一个基本的例子:

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'

If you need to observe changes made to a nested object, then you need to use a specialized library. I published 可观察的苗条 and it works like this:

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}}]

我在我的一个项目中使用了 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/melanke-watchjs@1.5.0/src/watch.min.js"></script>

This is as simple as this!

这对我有用

 $('#img').hide().attr('src', "path/newImage.jpg").fadeIn('slow');