13

私は Chrome で動作するこの関数を持っています。これは、finishedLoading という変数が値を変更したときにコンソールに出力されます。

Object.observe(finishedLoading, function(id, oldval, newval) {
         console.log('finished loading' + id + ' went from ' + oldval + ' to ' + newval);
     }

これは、他の多くの最新のブラウザー (firefox、safari など) では機能しません。より適切にサポートされる、使用できる代替手段はありますか? ありがとう!

4

1 に答える 1

12

より広くサポートされているアプローチは、Object.definePropertyです。たとえば、 definePropertyを使用して、オブジェクトの特定のプロパティを制御できます。

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';

上記の例は、definePropertyの使用方法を示しており、オブジェクトoのpropが変更されると、定義済みのセッター ( set ) が呼び出されます。

このリファレンスの最後に、 IE-8 でさえそれをサポートしていることがわかりますが、特定の条件下でのみサポートされています (IE8 は、DOM ノードで使用される Object.defineProperty のみをサポートしています)。

ただし、 thisが欠落しているため、 window オブジェクトにもプロパティが割り当てられるため、使用するときは注意してください。

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

o.b = 'abc';
console.log(window.value); // 'abc'

プロパティの古い値を追跡する方法

これはあなたの要求にもっと一致します:

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);

Object.defineProperty を使用してオブジェクト全体を観察する

それに加えて、オブジェクト全体を追跡し、プロパティが変更されているかどうかを追跡する関数を作成できます。

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;
于 2015-02-22T18:27:40.193 に答える