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

时间:2009-06-22 20:29:56

标签: javascript jquery javascript-events

请务必阅读以下所有评论。不推荐使用Object.Watch和Object.Observe。请参阅Elliot B对更新(截至2018年6月)方法的评论。


我一直在寻找一种简单的方法来监控对象或变量的变化,我找到了Object.watch(),这在Mozilla浏览器中得到支持,但不是IE。所以我开始四处寻找,看是否有人写过某种等价物。

关于我发现的唯一事情是a jQuery plugin,但我不确定这是否是最佳方式。我当然在大多数项目中使用jQuery,所以我并不担心jQuery方面......

无论如何,问题是:有人能告诉我一个jQuery插件的工作示例吗?我在制作它时遇到了问题...

或者,有没有人知道任何可以跨浏览器工作的更好的替代方案?

答案后更新

感谢大家的回复!我试过这里发布的代码: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html

但我似乎无法使其与IE一起工作。下面的代码在Firefox中运行良好,但在IE中没有任何作用。在Firefox中,每次更改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>");

7 个答案:

答案 0 :(得分:113)

(抱歉交叉发布,但我给同一个问题的答案在这里工作正常)

我刚才为此创建了一个小object.watch shim。它适用于IE8,Safari,Chrome,Firefox,Opera等。

答案 1 :(得分:18)

该插件只是使用计时器/间隔来重复检查对象的更改。也许还不错,但我个人希望作为观察者更加直接。

此处尝试将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);

不那么甜蜜,但作为观察员,您会立即得到通知。

答案 2 :(得分:11)

当前回答

使用新的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() from ES7Here's a polyfill.但是Object.observe() is now cancelled。对不起人!

答案 3 :(得分:6)

请注意,在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';

答案 4 :(得分:2)

您可以使用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
  }
})

答案 5 :(得分:1)

我在一个项目中使用了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>

这就是这么简单!

答案 6 :(得分:-2)

我也认为现在最好的解决方案是使用Watch.JS,在这里找到一个很好的教程:Listen/Watch for object or array changes in Javascript (Property changed event on Javascript objects)