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.

    Install

    npm i es7-object-observe

    DownloadsWeekly Downloads

    9

    Version

    2.0.6

    License

    MIT

    Last publish

    Collaborators

    • yohei-k-outt