observe a nested object
getters & setters
- Defining getters and setters
- Example:
var o = {
a: 7,
get b() {
return this.a + 1;
},
set c(x) {
this.a = x / 2
}
};
console.log(o.a); // 7
console.log(o.b); // 8
o.c = 50;
console.log(o.a); // 25
var log = ['test'];
var obj = {
get latest () {
if (log.length == 0) return undefined;
return log[log.length - 1]
}
}
console.log (obj.latest); // Will return "test".
var language = {
set current (name) {
this.log.push(name);
},
log: []
}
language.current = 'EN';
console.log(language.log); // ['EN']
language.current = 'FA';
console.log(language.log); // ['EN', 'FA']
Object.observe() (Deprecated)
- Doc
- Example:
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}]
delete obj.baz;
// [{name: 'baz', object: <obj>, type: 'delete', oldValue: 2}]
Object.defineProperty(obj, 'foo', {writable: false});
// [{name: 'foo', object: <obj>, type: 'reconfigure'}]
Object.setPrototypeOf(obj, {});
// [{name: '__proto__', object: <obj>, type: 'setPrototype', oldValue: <prototype>}]
Object.seal(obj);
// [
// {name: 'foo', object: <obj>, type: 'reconfigure'},
// {name: 'bar', object: <obj>, type: 'reconfigure'},
// {object: <obj>, type: 'preventExtensions'}
// ]
MutationObserver
// select the target node
var target = document.getElementById('some-id');
// create an observer instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };
// pass in the target node, as well as the observer options
observer.observe(target, config);
// later, you can stop observing
observer.disconnect();
Proxy
- Doc
- caniuse
- proxy-polyfill, harmony-reflect
- Example:
var handler = {
get: function(target, name){
return name in target?
target[name] :
37;
}
};
var p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;
console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37
observer a nested object (unstable version)
- setter & getter
var functionalProperty = function(obj, property, setter, getter) {
obj._data = obj._data || {};
obj._data[property] = obj[property];
Object.defineProperty(obj, property, {
enumerable: true,
set: function(x) {
setter && setter.call(this, property, x);
this._data[property] = x;
},
get: function() {
getter && getter.call(this, property);
return this._data[property];
}
})
}
var functionalProperties = function(obj, setter, getter) {
if (typeof obj !== 'object') return;
for (var i in obj) {
if (typeof obj[i] !== 'function' && i !== '_data') {
functionalProperty(obj, i, setter, getter)
// if (typeof obj[i] === 'object' && !(obj[i] instanceof Array)) {
// functionalProperties(obj[i], setter, getter)
// }
}
}
}
- proxy
var deepProxy = function(obj, setter) {
for (var i in obj) {
if (typeof obj[i] === 'object') {
obj[i] = deepProxy(obj[i], setter)
}
}
return new Proxy(obj, {set: setter});
}
- proxy-2
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#Methods
// http://stackoverflow.com/questions/41299642/how-to-use-javascript-proxy-for-nested-objects
var handler = {
get: function(target, key) {
if (typeof target[key] === 'object' && target[key] !== null) {
return new Proxy(target[key], handler)
} else {
return target[key];
}
},
set: function(target, key, value) {
console.log('set ' + key)
target[key] = value;
return true
}
}
var data = new Proxy({}, handler);
data.a = 'a';
data.b = {c: 'cc'}
data.b.c = 'abc'
data.d = {
a: 'a',
b: 'b',
c: {
e: 'e'
}
}
data.d.c.e = 'ee'
var data = new Proxy({a:'', b:''}, handler)
- proxy-3 (polyfill)
// https://github.com/GoogleChrome/proxy-polyfill.git var ele = {data: null}; var handler = { get: function(target, key) { if (typeof target[key] === 'object' && target[key] !== null) { return new Proxy(target[key], handler) } else { return target[key]; } }, set: function(target, key, value) { console.log('set ' + key) target[key] = value; return true } } ele = new Proxy(ele, handler); ele.data = {a: 'a', b: {bb: 'bb'}} ele.data.a = 'aa';