Firebug for Firefox has a nice feature, called "Break on property change", where I can mark any property of any object, and it will stop JavaScript execution right before the change.
I'm trying to achieve the same in Google Chrome, and I can't find the function in Chrome debugger. How do I do this in Google Chrome?
If you don't mind messing around with the source, you could redefine the property with an accessor.
// original object
var obj = {
someProp: 10
};
// save in another property
obj._someProp = obj.someProp;
// overwrite with accessor
Object.defineProperty(obj, 'someProp', {
get: function () {
return obj._someProp;
},
set: function (value) {
debugger; // sets breakpoint
obj._someProp = value;
}
});
Edit 2016.03: Object.observe is deprecated and removed in Chrome 50
**Edit 2014.05: `Object.observe` was added in Chrome 36**
Chrome 36 ships with native Object.observe implementation that can be leveraged here:
myObj = {a: 1, b: 2};
Object.observe(myObj, function (changes){
console.log("Changes:");
console.log(changes);
debugger;
})
myObj.a = 42;
If you want it only temporarily, you should store callback in a variable and call Object.unobserve when done:
myObj = {a: 1, b: 2};
func = function() {debugger;}
Object.observe(myObj, func);
myObj.a = 42;
Object.unobserve(myObj, func);
myObj.a = 84;
Note that when using Object.observe, you'll not be notified when the assignment didn't change anything, e.g. if you've written myObj.a = 1.
To see the call stack, you need to enable "async call stack" option in Dev Tools:
Original answer (2012.07):
A console.watch sketch as suggested by #katspaugh:
var console = console || {}; // just in case
console.watch = function(oObj, sProp) {
var sPrivateProp = "$_"+sProp+"_$"; // to minimize the name clash risk
oObj[sPrivateProp] = oObj[sProp];
// overwrite with accessor
Object.defineProperty(oObj, sProp, {
get: function () {
return oObj[sPrivateProp];
},
set: function (value) {
//console.log("setting " + sProp + " to " + value);
debugger; // sets breakpoint
oObj[sPrivateProp] = value;
}
});
}
Invocation:
console.watch(obj, "someProp");
Compatibility:
In Chrome 20, you can paste it directly in Dev Tools at runtime!
For completeness: in Firebug 1.10 (Firefox 14), you have to inject it in your website (e.g. via Fiddler if you can't edit the source manually); sadly, functions defined from Firebug don't seem to break on debugger (or is it a matter of configuration? please correct me then), but console.log works.
Note that in Firefox, `console.watch` already exists, due to Firefox's non-standard [`Object.watch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch). Hence in Firefox, you can watch for changes natively:
>>> var obj = { foo: 42 }
>>> obj.watch('foo', function() { console.log('changed') })
>>> obj.foo = 69
changed
69
Edit: Object.watch was removed in Firefox 57.
There is a library for this: BreakOn()
If you add it to Chrome dev tools as a snippet (sources --> snippets --> right-click --> new --> paste this --> run), you can use it anytime.
To use it, open the dev-tools and run the snippet. Then to break when myObject.myProperty is changed, call this from the dev-console:
breakOn(myObject, 'myProperty');
You could also add the library to your project's debug-build so you don't need to call breakOn again every time you refresh the page.
This can also be done by using the new Proxy object whose purpose is exactly that: intercepting the reads and writes to the object that is wrapped by the Proxy. You simply wrap the object you would like to observe into a Proxy and use the new wrapped object instead of your original one.
Example:
const originalObject = {property: 'XXX', propertyToWatch: 'YYY'};
const watchedProp = 'propertyToWatch';
const handler = {
set(target, key, value) {
if (key === watchedProp) {
debugger;
}
target[key] = value;
}
};
const wrappedObject = new Proxy(originalObject, handler);
Now use wrappedObject where you would supply originalObject instead and examine the call stack on break.
function debugProperty(obj, propertyName) {
// save in another property
obj['_' + propertyName] = obj[propertyName];
// overwrite with accessor
Object.defineProperty(obj, propertyName, {
get: function() {
return obj['_' + propertyName];
},
set: function(value) {
debugger; // sets breakpoint
obj['_' + propertyName] = value;
}
});
}
Decided to write my own version of this solution, save it in a snippet in Chrome's DevTools, and wrapped it in an IIFE that should support both Node and Browsers. Also changed the observer to use a scope variable rather than a property on the object, such that there is no possibility of name clashes, and any code that enumerates keys will not "see" the new "private key" that is created:
(function (global) {
global.observeObject = (obj, prop) => {
let value
Object.defineProperty(obj, prop, {
get: function () {
return value
},
set: function (newValue) {
debugger
value = newValue
},
})
}
})(typeof process !== 'undefined' ? process : window)
Building on the excellent solution by Alexandos Katechis, here is a version of the snippet that does not disturb the original value of the property. I renamed it to better match what I'm thinking when I use it.
Usage:
Add the snippet via Sources -> Snippets
When needed, press Command-O and choose to run the breakOnChange snippet
Call breakOnChange(anyObject, 'propertyName') in the console
Take the action that causes the change
Stops in debugger
This is very helpful for spotting things like a global library such as jQuery being stomped on by a third-party script.
(function (global) {
global.breakOnChange = (obj, prop) => {
let value = obj[prop]
Object.defineProperty(obj, prop, {
get: function () {
return value
},
set: function (newValue) {
debugger
value = newValue
},
})
}
})(typeof process !== 'undefined' ? process : window)
Chrome has this feature built-in in latest versions https://developers.google.com/web/updates/2015/05/view-and-change-your-dom-breakpoints.
So no more needs for custom libraries and solutions, just right click on DOM element in the inspector and choose 'Break on' -> 'attribute modifications' and that's it.
Related
Firebug for Firefox has a nice feature, called "Break on property change", where I can mark any property of any object, and it will stop JavaScript execution right before the change.
I'm trying to achieve the same in Google Chrome, and I can't find the function in Chrome debugger. How do I do this in Google Chrome?
If you don't mind messing around with the source, you could redefine the property with an accessor.
// original object
var obj = {
someProp: 10
};
// save in another property
obj._someProp = obj.someProp;
// overwrite with accessor
Object.defineProperty(obj, 'someProp', {
get: function () {
return obj._someProp;
},
set: function (value) {
debugger; // sets breakpoint
obj._someProp = value;
}
});
Edit 2016.03: Object.observe is deprecated and removed in Chrome 50
**Edit 2014.05: `Object.observe` was added in Chrome 36**
Chrome 36 ships with native Object.observe implementation that can be leveraged here:
myObj = {a: 1, b: 2};
Object.observe(myObj, function (changes){
console.log("Changes:");
console.log(changes);
debugger;
})
myObj.a = 42;
If you want it only temporarily, you should store callback in a variable and call Object.unobserve when done:
myObj = {a: 1, b: 2};
func = function() {debugger;}
Object.observe(myObj, func);
myObj.a = 42;
Object.unobserve(myObj, func);
myObj.a = 84;
Note that when using Object.observe, you'll not be notified when the assignment didn't change anything, e.g. if you've written myObj.a = 1.
To see the call stack, you need to enable "async call stack" option in Dev Tools:
Original answer (2012.07):
A console.watch sketch as suggested by #katspaugh:
var console = console || {}; // just in case
console.watch = function(oObj, sProp) {
var sPrivateProp = "$_"+sProp+"_$"; // to minimize the name clash risk
oObj[sPrivateProp] = oObj[sProp];
// overwrite with accessor
Object.defineProperty(oObj, sProp, {
get: function () {
return oObj[sPrivateProp];
},
set: function (value) {
//console.log("setting " + sProp + " to " + value);
debugger; // sets breakpoint
oObj[sPrivateProp] = value;
}
});
}
Invocation:
console.watch(obj, "someProp");
Compatibility:
In Chrome 20, you can paste it directly in Dev Tools at runtime!
For completeness: in Firebug 1.10 (Firefox 14), you have to inject it in your website (e.g. via Fiddler if you can't edit the source manually); sadly, functions defined from Firebug don't seem to break on debugger (or is it a matter of configuration? please correct me then), but console.log works.
Note that in Firefox, `console.watch` already exists, due to Firefox's non-standard [`Object.watch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch). Hence in Firefox, you can watch for changes natively:
>>> var obj = { foo: 42 }
>>> obj.watch('foo', function() { console.log('changed') })
>>> obj.foo = 69
changed
69
Edit: Object.watch was removed in Firefox 57.
There is a library for this: BreakOn()
If you add it to Chrome dev tools as a snippet (sources --> snippets --> right-click --> new --> paste this --> run), you can use it anytime.
To use it, open the dev-tools and run the snippet. Then to break when myObject.myProperty is changed, call this from the dev-console:
breakOn(myObject, 'myProperty');
You could also add the library to your project's debug-build so you don't need to call breakOn again every time you refresh the page.
This can also be done by using the new Proxy object whose purpose is exactly that: intercepting the reads and writes to the object that is wrapped by the Proxy. You simply wrap the object you would like to observe into a Proxy and use the new wrapped object instead of your original one.
Example:
const originalObject = {property: 'XXX', propertyToWatch: 'YYY'};
const watchedProp = 'propertyToWatch';
const handler = {
set(target, key, value) {
if (key === watchedProp) {
debugger;
}
target[key] = value;
}
};
const wrappedObject = new Proxy(originalObject, handler);
Now use wrappedObject where you would supply originalObject instead and examine the call stack on break.
function debugProperty(obj, propertyName) {
// save in another property
obj['_' + propertyName] = obj[propertyName];
// overwrite with accessor
Object.defineProperty(obj, propertyName, {
get: function() {
return obj['_' + propertyName];
},
set: function(value) {
debugger; // sets breakpoint
obj['_' + propertyName] = value;
}
});
}
Decided to write my own version of this solution, save it in a snippet in Chrome's DevTools, and wrapped it in an IIFE that should support both Node and Browsers. Also changed the observer to use a scope variable rather than a property on the object, such that there is no possibility of name clashes, and any code that enumerates keys will not "see" the new "private key" that is created:
(function (global) {
global.observeObject = (obj, prop) => {
let value
Object.defineProperty(obj, prop, {
get: function () {
return value
},
set: function (newValue) {
debugger
value = newValue
},
})
}
})(typeof process !== 'undefined' ? process : window)
Building on the excellent solution by Alexandos Katechis, here is a version of the snippet that does not disturb the original value of the property. I renamed it to better match what I'm thinking when I use it.
Usage:
Add the snippet via Sources -> Snippets
When needed, press Command-O and choose to run the breakOnChange snippet
Call breakOnChange(anyObject, 'propertyName') in the console
Take the action that causes the change
Stops in debugger
This is very helpful for spotting things like a global library such as jQuery being stomped on by a third-party script.
(function (global) {
global.breakOnChange = (obj, prop) => {
let value = obj[prop]
Object.defineProperty(obj, prop, {
get: function () {
return value
},
set: function (newValue) {
debugger
value = newValue
},
})
}
})(typeof process !== 'undefined' ? process : window)
Chrome has this feature built-in in latest versions https://developers.google.com/web/updates/2015/05/view-and-change-your-dom-breakpoints.
So no more needs for custom libraries and solutions, just right click on DOM element in the inspector and choose 'Break on' -> 'attribute modifications' and that's it.
Firebug for Firefox has a nice feature, called "Break on property change", where I can mark any property of any object, and it will stop JavaScript execution right before the change.
I'm trying to achieve the same in Google Chrome, and I can't find the function in Chrome debugger. How do I do this in Google Chrome?
If you don't mind messing around with the source, you could redefine the property with an accessor.
// original object
var obj = {
someProp: 10
};
// save in another property
obj._someProp = obj.someProp;
// overwrite with accessor
Object.defineProperty(obj, 'someProp', {
get: function () {
return obj._someProp;
},
set: function (value) {
debugger; // sets breakpoint
obj._someProp = value;
}
});
Edit 2016.03: Object.observe is deprecated and removed in Chrome 50
**Edit 2014.05: `Object.observe` was added in Chrome 36**
Chrome 36 ships with native Object.observe implementation that can be leveraged here:
myObj = {a: 1, b: 2};
Object.observe(myObj, function (changes){
console.log("Changes:");
console.log(changes);
debugger;
})
myObj.a = 42;
If you want it only temporarily, you should store callback in a variable and call Object.unobserve when done:
myObj = {a: 1, b: 2};
func = function() {debugger;}
Object.observe(myObj, func);
myObj.a = 42;
Object.unobserve(myObj, func);
myObj.a = 84;
Note that when using Object.observe, you'll not be notified when the assignment didn't change anything, e.g. if you've written myObj.a = 1.
To see the call stack, you need to enable "async call stack" option in Dev Tools:
Original answer (2012.07):
A console.watch sketch as suggested by #katspaugh:
var console = console || {}; // just in case
console.watch = function(oObj, sProp) {
var sPrivateProp = "$_"+sProp+"_$"; // to minimize the name clash risk
oObj[sPrivateProp] = oObj[sProp];
// overwrite with accessor
Object.defineProperty(oObj, sProp, {
get: function () {
return oObj[sPrivateProp];
},
set: function (value) {
//console.log("setting " + sProp + " to " + value);
debugger; // sets breakpoint
oObj[sPrivateProp] = value;
}
});
}
Invocation:
console.watch(obj, "someProp");
Compatibility:
In Chrome 20, you can paste it directly in Dev Tools at runtime!
For completeness: in Firebug 1.10 (Firefox 14), you have to inject it in your website (e.g. via Fiddler if you can't edit the source manually); sadly, functions defined from Firebug don't seem to break on debugger (or is it a matter of configuration? please correct me then), but console.log works.
Note that in Firefox, `console.watch` already exists, due to Firefox's non-standard [`Object.watch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch). Hence in Firefox, you can watch for changes natively:
>>> var obj = { foo: 42 }
>>> obj.watch('foo', function() { console.log('changed') })
>>> obj.foo = 69
changed
69
Edit: Object.watch was removed in Firefox 57.
There is a library for this: BreakOn()
If you add it to Chrome dev tools as a snippet (sources --> snippets --> right-click --> new --> paste this --> run), you can use it anytime.
To use it, open the dev-tools and run the snippet. Then to break when myObject.myProperty is changed, call this from the dev-console:
breakOn(myObject, 'myProperty');
You could also add the library to your project's debug-build so you don't need to call breakOn again every time you refresh the page.
This can also be done by using the new Proxy object whose purpose is exactly that: intercepting the reads and writes to the object that is wrapped by the Proxy. You simply wrap the object you would like to observe into a Proxy and use the new wrapped object instead of your original one.
Example:
const originalObject = {property: 'XXX', propertyToWatch: 'YYY'};
const watchedProp = 'propertyToWatch';
const handler = {
set(target, key, value) {
if (key === watchedProp) {
debugger;
}
target[key] = value;
}
};
const wrappedObject = new Proxy(originalObject, handler);
Now use wrappedObject where you would supply originalObject instead and examine the call stack on break.
function debugProperty(obj, propertyName) {
// save in another property
obj['_' + propertyName] = obj[propertyName];
// overwrite with accessor
Object.defineProperty(obj, propertyName, {
get: function() {
return obj['_' + propertyName];
},
set: function(value) {
debugger; // sets breakpoint
obj['_' + propertyName] = value;
}
});
}
Decided to write my own version of this solution, save it in a snippet in Chrome's DevTools, and wrapped it in an IIFE that should support both Node and Browsers. Also changed the observer to use a scope variable rather than a property on the object, such that there is no possibility of name clashes, and any code that enumerates keys will not "see" the new "private key" that is created:
(function (global) {
global.observeObject = (obj, prop) => {
let value
Object.defineProperty(obj, prop, {
get: function () {
return value
},
set: function (newValue) {
debugger
value = newValue
},
})
}
})(typeof process !== 'undefined' ? process : window)
Building on the excellent solution by Alexandos Katechis, here is a version of the snippet that does not disturb the original value of the property. I renamed it to better match what I'm thinking when I use it.
Usage:
Add the snippet via Sources -> Snippets
When needed, press Command-O and choose to run the breakOnChange snippet
Call breakOnChange(anyObject, 'propertyName') in the console
Take the action that causes the change
Stops in debugger
This is very helpful for spotting things like a global library such as jQuery being stomped on by a third-party script.
(function (global) {
global.breakOnChange = (obj, prop) => {
let value = obj[prop]
Object.defineProperty(obj, prop, {
get: function () {
return value
},
set: function (newValue) {
debugger
value = newValue
},
})
}
})(typeof process !== 'undefined' ? process : window)
Chrome has this feature built-in in latest versions https://developers.google.com/web/updates/2015/05/view-and-change-your-dom-breakpoints.
So no more needs for custom libraries and solutions, just right click on DOM element in the inspector and choose 'Break on' -> 'attribute modifications' and that's it.
This is what I have so far: http://jsfiddle.net/beCVL/5/
This is how I'm trying to override the default cloneNode:
Object.defineProperty(Object.prototype, "cloneNode", {
get: cloneNode2,
set: cloneNode2
});
but it's not working, so, I think Object.prototype doesn't have cloneNode, but Element.prototype doesn't either.
So, which class do I need to use to override cloneNode, assuming my method is correct?
It's a property of Node.prototype https://developer.mozilla.org/En/DOM/Node.cloneNode
Node.prototype.cloneNode = function() {}
However, modifying built in objects may give you grief in the future. If possible, you should create a different function and use that instead, that way, existing code that uses cloneNode won't break.
Try using:
Node.prototype.cloneNode = cloneNode2;
Object.defineProperty is not used for this purpose. Here's an example of a use for it:
var o = {};
Object.defineProperty(o, 'blah', {
'get': function () { return 'asdf'; },
'set': function (x) { alert(x); }
});
alert(o.blah); // alerts 'asdf'
o.blah = 'fdsa'; // alerts 'fdsa'
Apparently, this only works in Chrome.
To solve the actual problem, it should be simple enough to just replace the RGB codes with its equivalent hex code.
function decToHex(a) {
return ('00' + (+a).toString(16)).substr(-2);
}
function replaceRGB(str) {
return str.replace(/rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)/, function (_, r, g, b) {
return "#" + decToHex(r) + decToHex(g) + decToHex(b);
});
}
replaceRGB("color: rgb(255, 0, 0)") // "color: #ff0000"
This series of fiddles is a work in progress, but it reimplements cloneNode's functionality. http://jsfiddle.net/beCVL/19/
as of April 4th, 10:53am EST, it needs to work with IE, as IE doesn't have a Node object.
Note, that in IE, prototype functions can't be overridden. So, all instances of cloneNode have to be replaced by a function that determines which version of cloneNode to use.
This works in modern Chrome/Firefox/Opera but fails in IE8. Haven't tried it in IE9. How can I make this cross-browser compatible, including IE7+? (Fiddle here.)
var foo = {
get test(){ return 'Works'; }
};
// foo.test should be 'Works'
I've seen some usage with __defineGetter__ but that threw an 'unrecognized method' error in IE8.
Here is the workaround for IE6/7/8. I performed the test and it works very well!
Update: The link is broken, you can see the code of from my testing here:
// Super amazing, cross browser property function, based on http://thewikies.com/
function addProperty(obj, name, onGet, onSet) {
// wrapper functions
var
oldValue = obj[name],
getFn = function () {
return onGet.apply(obj, [oldValue]);
},
setFn = function (newValue) {
return oldValue = onSet.apply(obj, [newValue]);
};
// Modern browsers, IE9+, and IE8 (must be a DOM object),
if (Object.defineProperty) {
Object.defineProperty(obj, name, {
get: getFn,
set: setFn
});
// Older Mozilla
} else if (obj.__defineGetter__) {
obj.__defineGetter__(name, getFn);
obj.__defineSetter__(name, setFn);
// IE6-7
// must be a real DOM object (to have attachEvent) and must be attached to document (for onpropertychange to fire)
} else {
var onPropertyChange = function (e) {
if (event.propertyName == name) {
// temporarily remove the event so it doesn't fire again and create a loop
obj.detachEvent("onpropertychange", onPropertyChange);
// get the changed value, run it through the set function
var newValue = setFn(obj[name]);
// restore the get function
obj[name] = getFn;
obj[name].toString = getFn;
// restore the event
obj.attachEvent("onpropertychange", onPropertyChange);
}
};
obj[name] = getFn;
obj[name].toString = getFn;
obj.attachEvent("onpropertychange", onPropertyChange);
}
}
I don't believe you can.
In IE8 and lower, property access is mere property access. There's no way to run function code without explicitly invoking the function.
I think in IE8 you may be able to with DOM elements, but I don't believe it works for regular native objects.
There is a "definePropery" method that will essentially allow you to create accessor methods (getters/setters) on Objects without the need to invoke a function call like setProp() / getProp().
The syntax is a little weird but I've been able to get this to work on Firefox, Chrome, Safari and IE9.
Say I have JavaScript Object called "Person".
function Person()
{
// set a default value //
this.__name = 'John';
// add getter & setter methods //
Object.defineProperty(this, "name", {
get: function() {
// additional getter logic
return this.__name;
},
set: function(val) {
this.__name = val;
// additional setter logic
}
});
}
var p = new Person();
console.log(p.name); // 'John'
p.name = 'Stephen';
console.log(p.name); // 'Stephen'
More info on Mozilla's site here.
You cannot, the syntax is not supported in browsers that did not implement it. Its going to be quite a while before you'll be able to use that syntax without having CBC problems. Be grateful IE6 is pretty much dead in North America.
Im wondering if someone might be able to help me with something that i think it fairly straight forward:
Essentially i want to extend the prototypes of all datatypes (including intrinsic types), to allow some kind of custom functions, consider:
var x = "some string";
var y = 101;
x = "some other value";
y++;
x.onChange();
y.onChange();
This is the basic idea im after, but really what i want is to actually have the onChange (in this example) to be different so a new function for the actual variable (rather than a stardard prototype extension), ie:
x.onChange = function() {
alert("x.onChange");
}
y.onChange = function() {
alert("y.onChange");
}
This doesnt seem to work but i must be missing something quite simple no? I mean surely i can extend all object and types and add on new functions... no?
Any help would be greatly appreciated!
I might be tempted to approach this not by trying to add methods to existing types, but to create an object that can wrap a primative type. I would call this "observing" a value, and might implement it something like this:
function observable(v){
this.value = v;
this.valueChangedCallback = null;
this.setValue = function(v){
if(this.value != v){
this.value = v;
this.raiseChangedEvent(v);
}
};
this.getValue = function(){
return this.value;
};
this.onChange = function(callback){
this.valueChangedCallback = callback;
};
this.raiseChangedEvent = function(v){
if(this.valueChangedCallback){
this.valueChangedCallback(v);
}
};
}
This can then be used to observe changes in any value (so long as that value is then changed only by methods on the observable class - a small detraction IMO).
Something like this would work with the above code:
var obs = new observable(123);
obs.onChange(function(v){
alert("value changed to: " + v);
});
// the onChange callback would be called after something like obs.setValue(456);
Live example here --> http://jsfiddle.net/MeAhz/
Extend the object prototype:
Object.prototype.foo = function() { alert('hello world'); };
var a = 1;
a.foo();
The standard DEPRECATED way : Object.observe()
The Object.observe() method was used for asynchronously observing the
changes to an object. It provided a stream of changes in the order in
which they occur. However, this API has been deprecated and removed
from browsers.
let myObservdObject = Object.observe( { a : 'foo' }, e=>console.log('change!', e) );
myObservdObject.a = 'bee';
// callback gets executed
// and prints 'changed! in console, with the change event data
But proxies arrived to the Standard (ES6) an Object.Observe became deprecated and, in consecuence, unsupported by the browsers.
Proxies are the new way to observe... but implement a generic observer requires a more complex implementation, in comparsion with the way Object.observe used to provide us.
Observe value changes with third party libraries
You can find arround many implementations based in proxies.
Some of them implement the Observer pattern, wich forces you to set or get the values using specific methods :
Observe :
https://www.npmjs.com/package/observe
// define your object
var object = {a:'bee'};
// generate an observer
var observer = observe(object);
// declare the onchange event handler
observer.on( 'change', change=> console.log(change) );
// ready!
// set the value of 'a' and see how the callback is executed...
observer.set('a', 'foo')
// get the new value
observer.get('a') // returns 'foo'
Other libraries instead, let you interact with your variables using a more natural way:
WatchJS :
https://github.com/melanke/Watch.JS/
// define your object
var object = {a:'bee'};
// generate an observer and declare de hadler
watch(object , "a" , e=>console.log(e) );
// ready!
// set the value of 'a' and see how the callback is executed...
object.a = 'foo';
// get the new value
object.a // returns 'foo'
My own apprach : deep-observer
All the implementaions have their own caveats, and none of them was working for my purposes, so i had to implement my own approach.
The result is a highly customizable Observer method with a really small footprint ( <100 bytes gziped)
Deep-observer : https://www.npmjs.com/package/deep-observer
// create an observable object
const myObserved = new Observer( { a : 'bee' } , e=>console.log(e) ),
// perform a modification
myObserved.a = 'foo';
// console : { action:'update', oldValue:'bee', object:{a:'foo'}, name:'a' }
myObserved.a; // returns 'foo'