Object.observe — not supported by all major browsers, what can I use as an alternative?

前端 未结 1 861
天涯浪人
天涯浪人 2021-02-02 17:18

I have this function that works in Chrome, which prints to the console when a variable called finishedLoading changes values.

Object.observe(finishedLoading, fu         


        
相关标签:
1条回答
  • 2021-02-02 18:04

    A more widely supported approach could be Object.defineProperty. defineProperty can be used to have some control on a certain property of an object for instance:

    var o = { prop: '' };
    Object.defineProperty(o, 'prop', {
      get: function() { return this.value; },
      set: function(newValue) {
        // a certain property is being changed
        alert('is changed');
        this.value = newValue; 
      }
    });
    
    o.prop = 'Johnson';
    

    The above example shows how you can use defineProperty and when prop of object o is altered a defined setter (set) is called.

    At the bottom of this reference you can see that even IE-8 supports it but only under certain conditions (IE8 only support Object.defineProperty to be used on DOM nodes).

    But be careful when using it because this would assign a property to the window object as well because of a missing this:

    var o = { b:''};
    Object.defineProperty(o, 'b', {
      get: function() { return value; },
      set: function(newValue) { value = newValue; },
    });
    
    o.b = 'abc';
    console.log(window.value); // 'abc'
    

    Way to track old value of a property

    This matches more your request:

    var o = { prop: '' };
    
    Object.defineProperty(o, 'prop', {
      get: function() { return this.propValue; },
      set: function(newValue) {
        // an certain property is being changed
        console.log('old-value: ',this['oldprop']);
        console.log('new-value: ',newValue);
        this.propValue = newValue; 
        this['oldprop'] = this.propValue;
      }
    });
    
    o['prop'] = 'joseph';
    console.log(o);
    o['prop'] = 'jack';
    console.log(o);
    o['prop'] = 'john';
    console.log(o);
    

    Observe whole Object by using Object.defineProperty

    And in addition to that you could make a function that tracks a whole object and whether any property is being changed:

    function observeObject(obj){
    
      var keys = Object.keys(obj);
    
      for(var k=0; k < keys.length; k++){
    
        var key = keys[k];
    
        (function(key){
    
          var keyName = key+'value';
          var oldKeyName = 'old'+key+'value';
    
          obj[oldKeyName] = obj[key];
    
          Object.defineProperty(obj, key, {
            get: function() { return this[keyName]; },
            set: function(newValue) {
    
              console.log('old-value: ',this[oldKeyName]);
              console.log('new-value: ',newValue);
    
              this[keyName] = newValue; 
              this[oldKeyName] = this[keyName];
    
            }
          });
    
    
    
        })(key);
    
      }
    
    }
    
    
    var person = { name : 'jack', age: 26 };
    
    observeObject(person);
    
    person.name = 'john';
    person['age'] = 27;
    
    0 讨论(0)
提交回复
热议问题