Object.watch() for all browsers?

前端 未结 8 671
囚心锁ツ
囚心锁ツ 2020-11-22 13:06

Please note that Object.Watch and Object.Observe are both deprecated now (as of Jun 2018).


I was looking for an easy way to monitor an object

相关标签:
8条回答
  • 2020-11-22 13:14

    you can use Object.defineProperty.

    watch the property bar in 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
      }
    })
    
    0 讨论(0)
  • 2020-11-22 13:19

    That plugin simply uses a timer/interval to repeatedly check for changes on an object. Maybe good enough but personally I would like more immediacy as an observer.

    Here's an attempt at bringing watch/unwatch to 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);
    

    You do:

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

    Not as sweet, but as an observer you are notified immediately.

    0 讨论(0)
  • 2020-11-22 13:24

    I have used Watch.js in one of my projects. And it is working fine.One of the main advantage of using this library is :

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

    The example is given below

    //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!

    0 讨论(0)
  • 2020-11-22 13:26

    (Sorry for the cross-posting, but this answer I gave to a similar question works fine here)

    I have created a small object.watch shim for this a while ago. It works in IE8, Safari, Chrome, Firefox, Opera, etc.

    0 讨论(0)
  • 2020-11-22 13:28

    Current Answer

    Use the new Proxy object, which can watch changes to it's target.

    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

    You could have used Object.observe() from ES7. Here's a polyfill. But Object.observe() is now cancelled. Sorry people!

    0 讨论(0)
  • 2020-11-22 13:36

    The answers to this question are a bit outdated. Object.watch and Object.observe are both deprecated and should not be used.

    Today, you can now use the Proxy object to monitor (and intercept) changes made to an object. Here's a basic example:

    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 Observable Slim 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}}]
    
    0 讨论(0)
提交回复
热议问题