2016-03-28 8 views
28

Czy istnieje alternatywne podejście?Dlaczego obiekt Object.observe() został wycofany?

Czy istnieje inny sposób na wykrycie zmian w obiekcie?

Istnieje metoda proxy, ale może ktoś mi powiedzieć, w jaki sposób można to osiągnąć przy użyciu serwera proxy:

var obj = { 
    foo: 0, 
    bar: 1 
}; 

Object.observe(obj, function(changes) { 
    console.log(changes); 
}); 

obj.baz = 2; 
// [{name: 'baz', object: <obj>, type: 'add'}] 

obj.foo = 'hello'; 
// [{name: 'foo', object: <obj>, type: 'update', oldValue: 0}] 
+2

'Proxy()' jest już dostępne! – Jai

+1

[Proxy] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy) –

+1

Lub użyj [getter] (https://developer.mozilla.org/en/docs/ Web/JavaScript/Reference/Functions/get) lub [setter] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/set) –

Odpowiedz

34

Można to osiągnąć z pobierające i ustawiające.

var obj = { 
    get foo() { 
    console.log({ name: 'foo', object: obj, type: 'get' }); 
    return obj._foo; 
    }, 
    set bar(val) { 
    console.log({ name: 'bar', object: obj, type: 'set', oldValue: obj._bar }); 
    return obj._bar = val; 
    } 
}; 

obj.bar = 2; 
// {name: 'baz', object: <obj>, type: 'set', oldValue: undefined} 

obj.foo; 
// {name: 'foo', object: <obj>, type: 'get'} 

Alternatywnie, w przeglądarce obsługującej serwery proxy można napisać bardziej ogólne rozwiązanie.

var obj = { 
    foo: 1, 
    bar: 2 
}; 

var proxied = new Proxy(obj, { 
    get: function(target, prop) { 
    console.log({ type: 'get', target, prop }); 
    return Reflect.get(target, prop); 
    }, 
    set: function(target, prop, value) { 
    console.log({ type: 'set', target, prop, value }); 
    return Reflect.set(target, prop, value); 
    } 
}); 

proxied.bar = 2; 
// {type: 'set', target: <obj>, prop: 'bar', value: 2} 

proxied.foo; 
// {type: 'get', target: <obj>, prop: 'bar'} 
+1

Dzięki Dan, próbuję uruchomić pierwszy przykład, że działa pętla infinte. Używam tego przykładu w chrome 48.x – Shad

+0

Ups. Przegapiłeś podkreślenie. –

+0

@Dan tak, jak Chad wspomniał, że twój pierwszy soln uruchamia nieskończoną pętlę. – Nirus

10

@Dan solution jest poprawna.

W przypadku, gdy chcesz obsługiwać przeglądarki, które są dość starsze, sugeruję, aby przejść do polyfill.

lub użyj Object.defineProperties API który jest obsługiwany w IE 9.

var obj = Object.defineProperties({}, { 
    "foo":{ 
     get:function(){ 
      console.log("Get:"+this.value); 
     }, 
     set:function(val){ 
      console.log("Set:"+val); 
      this.value = val; 
     } 
    }, 

    "bar":{   
     get:function(){ 
      console.log("Get:"+this.value); 
     }, 
     set:function(val){ 
      console.log("Set:"+val); 
      this.value = val; 
     } 
    } 
}); 
5

Disclaimer: Jestem autorem biblioteki object-observer sugerowane poniżej.

Nie skorzystałbym z rozwiązania pobierającego/ustawiającego - jest skomplikowany, nie skalowalny i nie do utrzymania. Backbone wykonał swoje dwustronne wiązanie w ten sposób, a podstawa do poprawnego działania była całkiem kawałkiem kodu.

Serwery proxy to najlepszy sposób na osiągnięcie tego, czego potrzebujesz, po prostu dodaj do przykładów powyżej niektórych rejestracji i zarządzania oddzwanianiem i wykonaj je po wprowadzeniu zmian.

Jeśli chodzi o biblioteki polyfill: niektóre/większość z nich realizowanych z wykorzystaniem "brudnej kontroli" lub techniki głosowania - nieefektywne, nieskuteczne. Czasami zdarza się to w przypadku polyfill wskazanego przez Nirus powyżej.

Polecam, aby pobrać bibliotekę, która wykonuje obserwację za pośrednictwem serwerów proxy. Jest ich kilka, object-observer będąc jednym z nich: napisany specjalnie dla tego przypadku, wykorzystuje natywne proxy, zapewnia głęboką obserwację drzew itp.

+0

Co ze wsparciem przeglądarki? [** Serwery proxy nie mogą być polifilizowane ani transpiled **] (https://stackoverflow.com/questions/35025204/javascript-proxy-support-in-babel), więc IMO używający serwerów proxy nie jest dobrym pomysłem jeszcze środowiska produkcyjne! –

+0

Ta implementacja nie działa w żadnym środowisku, które nie obsługuje obiektów Proxy. Jednak wszystkie główne przeglądarki do pobrania już istnieją (Chrome, Firefox, Opera), a nawet Edge. Dostępne są również wersje mobilne. Jedyne, co mogę zobaczyć, to IE pre-Edge - cóż, osobiście zostawiłem to. – GullerYA

+0

W świecie korporacyjnym często rezygnacja z IE nie jest opcją. –

Powiązane problemy