2015-02-22 11 views
13

Mam tę funkcję, która działa w przeglądarce Chrome, która drukuje do konsoli, gdy zmienna nazywa się finishedLoading zmienia wartości.Object.observe - nieobsługiwany przez wszystkie główne przeglądarki, z czego mogę korzystać jako alternatywa?

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

To nie działa w wielu innych nowoczesnych przeglądarkach (np. Firefox, safari). Czy istnieje alternatywa, z której mogę skorzystać, która byłaby lepiej wspierana? Dzięki!

+0

Użyj wywołania zwrotnego lub obietnicy? –

+2

Zobacz http://polyfills.io/ – KooiInc

+0

Wow, polyfills.io jest świetny. Po prostu dodałem, że jedna linia i wszystko działa pięknie. Dzięki! – pomegranate

Odpowiedz

13

Szerzej obsługiwanym podejściem może być Object.defineProperty. defineProperty można stosować mieć pewną kontrolę na niektórych właściwości obiektu, na przykład:

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

Powyższy przykład pokazuje, jak można wykorzystać defineProperty a kiedy prop obiektu o ulega zmianie zdefiniowany seter (zestaw) jest wywoływany.

Na dole tego reference widać, że nawet IE-8 obsługuje go, ale tylko pod pewnymi warunkami (IE8 obsługuje tylko Object.defineProperty do wykorzystania w węzłach DOM).

Ale bądź ostrożny podczas korzystania z niego, ponieważ byłoby to przypisać obiekt do obiektu window, jak również ze względu na brakujący ten:

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

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

sposób śledzenia starą wartość właściwości

To pasuje bardziej do zapytania:

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

przestrzegać całego obiektu za pomocą Object.defineProperty

aw Poza tym można zrobić funkcję, która śledzi cały obiekt i czy nieruchomość jest Zmieniono:

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; 
+2

'widać, że nawet IE-8 obsługuje go, ale pod pewnymi warunkami". IE8 obsługuje tylko 'Object.defineProperty' do użycia w węzłach DOM. – andlrc

+0

@Null dzięki za notatkę, został wstawiony. – Blauharley

+0

Dziękujemy za naprawdę pomocną odpowiedź! – pomegranate