Object.watch() 适用于所有浏览器?

IT技术 javascript jquery dom-events
2021-01-30 15:36:12

请注意,Object.WatchObject.Observe现在都已弃用(截至 2018 年 6 月)。


我一直在寻找一种简单的方法来监视对象或变量的变化,我发现Object.watch()Mozilla 浏览器支持它,但不支持 IE。所以我开始四处寻找,看看是否有人写过类似的东西。

我发现的唯一东西是 jQuery plugin,但我不确定这是否是最好的方法。我当然在我的大部分项目中使用 jQuery,所以我不担心 jQuery 方面......

无论如何,问题是:有人可以向我展示该 jQuery 插件的工作示例吗?我在使它工作时遇到问题...

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

回答后更新

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

但我似乎无法使其与 IE 一起使用。下面的代码在 Firefox 中运行良好,但在 IE 中不起作用。在 Firefox 中,每次watcher.status更改时,都会调用document.write()inwatcher.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>");
6个回答

(抱歉交叉发布,但我对类似问题的回答在这里很好用)

不久前,我为此创建了一个小的object.watch 垫片它适用于 IE8、Safari、Chrome、Firefox、Opera 等。

我知道想法Object.defineProperty()存在。我最终查看了MDN参考以了解它是如何工作的。
2021-03-11 15:36:12
jsfiddle.net/kSWxP提示:使用 Firefox(Chrome 中不打印后一条语句)
2021-03-16 15:36:12
关于如何使用它以及它在内部如何工作的解释对于我们这些不是 JS 大师的人来说会很好,谢谢。
2021-03-19 15:36:12

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

这是将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);

不是那么甜蜜,但作为观察者,您会立即收到通知。

是的,注意那些时间戳……无需投票,crescentfresh 还向帖子添加了更多信息,即使它是相同的链接。同时,我尝试了在该页面上找到的代码,但仍然发现问题。不过我可能忽略了一些东西。我已经用更多信息更新了我的原始帖子......
2021-03-21 15:36:12

这个问题的答案有点过时了。Object.watchObject.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年的旧答案

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

@infomofo 嗨,您想在项目页面上打开一个问题,并提供所有详细信息吗?我还没有在 iOS 上测试过它,但我会调查这个问题。
2021-03-30 15:36:12
嗯,我无法让这个 polyfill 在 ios safari 上工作。我得到错误:未定义不是一个函数(评估 'Object.observe(a.imgTouch,function(a){console.debug("lastX: "+a)})')
2021-04-09 15:36:12

请注意,在 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';
与 2018 年一样,这已被弃用,所有主要浏览器都不再支持
2021-04-01 15:36:12