Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why has Object.observe() been deprecated

Tags:

javascript

Is there an alternative approach?

Is there another way to do change detection in object?

There is the Proxy method, but can anyone tell me how can I achieve this using 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}] 
like image 941
Shad Avatar asked Mar 28 '16 08:03

Shad


People also ask

What does it mean when a variable is deprecated in JavaScript?

What does “deprecation” actually mean? First, let's start by clarifying that the deprecation is just a status applied to a software feature. It indicates that this feature should be avoided, typically because it has been superseded. Deprecation may also indicate that the feature will be removed in the future.

What is observe in JavaScript?

observe() The IntersectionObserver method observe() adds an element to the set of target elements being watched by the IntersectionObserver . One observer has one set of thresholds and one root, but can watch multiple target elements for visibility changes in keeping with those.

What is proxy in JS?

In JavaScript, proxies (proxy object) are used to wrap an object and redefine various operations into the object such as reading, insertion, validation, etc. Proxy allows you to add custom behavior to an object or a function.


2 Answers

You can achieve this with getters and setters.

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: 'bar', object: <obj>, type: 'set', oldValue: undefined}  obj.foo; // {name: 'foo', object: <obj>, type: 'get'} 

Alternatively, in a browser with support for Proxies, you can write a more generic solution.

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'} 
like image 114
Dan Prince Avatar answered Sep 22 '22 03:09

Dan Prince


Disclaimer: I'm the author of the object-observer library suggested below.

I'd not go with getters/setters solution - it's complicated, not scalable and not maintainable. Backbone did their two-way binding that way and the boilerplate to get it working correctly was quite a piece of a code.

Proxies is the best way to achieve what you need, just add to the examples above some callbacks registration and management and execute them upon a changes.

As regarding to the polyfill libraries: some/most of these implemented utilizing 'dirty check' or polling technique - not efficient, not performant. Occasionally, this is the case of the polyfill pointed out by Nirus above.

I'd recommend to pick up some library that does observation via Proxies. There are a few out there, object-observer being one of them: written for this use-case exactly, utilizes native Proxies, provides deep-tree observation etc.

like image 31
GullerYA Avatar answered Sep 25 '22 03:09

GullerYA