es7-object-observe

2.0.6 • Public • Published

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

5. To prevent memory leaks, call oo.Object.unobserve before oo-object gets unused.

Package Sidebar

Install

npm i es7-object-observe

Weekly Downloads

1

Version

2.0.6

License

MIT

Last publish

Collaborators

  • yohei-k-outt