es7-object-observe
v2.0.6
Published
Object.observe polyfill without dirty checking
Downloads
42
Maintainers
Readme
es7-object-observe
Introduction
es7-object-observe is Object.observe polyfill without dirty-checking.
const oo = require('es7-object-observe');
const obj = new oo.Object({ foo: 0, bar: 1 });
oo.Object.observe(obj, (changes) => { console.log(changes); });
obj.foo = 'hello';
obj.bar = 'world';
// [
// {name: 'foo', object: <obj>, type: 'update', oldValue: 0},
// {name: 'bar', object: <obj>, type: 'update', oldValue: 1},
// ]
const arr = new oo.Array(['a', 'b', 'c']);
oo.Array.observe(arr, (changes) => { console.log(changes); });
arr[1] = 'B';
arr.splice(1, 2, 'beta', 'gamma', 'delta');
// [
// {type: 'update', object: <arr>, name: '1', oldValue: 'b'},
// {type: 'splice', object: <arr>, index: 1, removed: ['B', 'c', 'd'], addedCount: 3}
// ]
Install
npm install es7-object-observe
Caveats
es7-object-observe(oo) is based on spec proposal and almost the same as chrome implementation, but there are some differences.
1. Wrap object in oo.Object or oo.Array.
const obj = oo.Object({ id: 1 });
2. Use oo.Object.method to oo-object.
function observer(changes) {
console.log(changes);
}
oo.Object.observe(obj, observer, ['update', 'reconfigure', 'preventExtensions']);
oo.Object.defineProperty(obj, 'a', { enumerable: false });
oo.Object.preventExtensions(obj);
// [
// { object: obj, type: 'reconfigure', name: 'a' },
// { object: obj, type: 'preventExtensions' }
// ]
oo.Object.unobserve(obj, observer);
3. Use special methods 'set' and 'delete' to notify 'add' and 'delete'.
// Bad example; they can't deliver changes.
obj.a = 'b';
delete obj.a;
obj.set('a', 'b');
obj.delete('a');
// [
// { object: obj, type: 'add', name: 'a' },
// { object: obj, type: 'delete', name: 'a', oldValue: 'b' }
// ]
I prefer to use oo-object with oo.Object.seal, because it can eliminates the need for uncool 'set' and 'delete'.
oo.Object.seal(obj);
// Another example
class Square extends oo.Object {
constructor(x, y, width, height) {
super({x, y, width, height});
oo.Object.seal(this);
}
scale(ratio) {
Square.getNotifier(this).performChange('scale', () => {
this.width *= ratio;
this.height *= ratio;
return {
ratio: ratio
};
});
}
static observe(square, callback) {
return oo.Object.observe(square, callback, ['update', 'scale']);
}
}
4. oo.Array is not 'array' but 'array-like object'.
const arr = oo.Array([1, 2, 3, 4]);
// arr is not array.
(arr instanceof Array) !== true
// But you can use all methods of Array.
arr.forEach((v) => {
...
});
// You can use for-loop on a browser supporting iterator.
for (let i of arr) {
// not working on IE and Safari...
}
// arr.method which returns 'array' returns 'array', not 'oo-array'.
arr.copyWithin(...); // returns 'normal' array