关于所有浏览器的javascript:Object.watch()?

Object.watch() for all browsers?

请务必阅读以下所有评论。object.watch和object.observe都已弃用。有关更新的(截至2018年6月)方法,请参见Elliot B的评论。

我在寻找一种简单的方法来监视对象或变量的变化,我发现了Mozilla浏览器支持的Object.watch(),但不是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中)。但是,如果不调用回调函数,那么这就没有意义了…:)

我错过什么了吗?

1
2
3
4
5
6
7
8
9
10
11
12
var options = {'status': 'no status'},
watcher = createWatcher(options);

watcher.watch("status", function(prop, oldValue, newValue) {
  document.write("old:" + oldValue +", new:" + newValue +"");
  return newValue;
});

watcher.status = 'asdf';
watcher.status = '1234';

document.write(watcher.status +"");


(很抱歉,我给了一个类似问题的答案,但在这里没问题)

我已经创建了一个小对象。请注意这一点。它适用于IE8、Safari、Chrome、Firefox、Opera等。


该插件只使用计时器/间隔来重复检查对象上的更改。也许足够好,但就我个人而言,作为一个观察者,我更想直接一点。

这里有一个尝试将watchunwatch引入IE:http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html。

它确实改变了Firefox添加观察者的语法。而不是:

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

你这样做:

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

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


当前答案

使用新的代理对象,它可以监视对其目标的更改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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年的老答案

您可以使用ES7中的object.observer()。这是一个填充物。但是object.observe()现在被取消了。对不起人们!


请注意,在Chrome36及更高版本中,您也可以使用Object.observe。这实际上是未来EcmaScript标准的一部分,而不是像Mozilla的Object.watch那样的特定于浏览器的功能。

Object.observe只在对象属性上工作,但比Object.watch性能更高(用于调试目的,而不是用于生产)。

1
2
3
4
5
6
7
var options = {};

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

options.foo = 'bar';


可以使用object.defineproperty。

观察foo中的财产bar

1
2
3
4
5
6
7
8
9
Object.defineProperty(foo,"bar", {
  get: function (val){
      //some code to watch the getter function
  },

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


我在一个项目中使用了watch.js。它工作得很好。使用这个库的一个主要优势是:

"With Watch.JS you will not have to change the way you develop."

示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
//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";
1
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src/watch.min.js">

就这么简单!


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