3

Consider the code below :

function createFoo() {
  var val;

  function Foo() {}
  Object.defineProperty(Foo.prototype, 'foo', {
    get: function () {
      return val;
    },
    set: function (value) {
      val = value; 
      document.write('foo value set to : ', value);
    }
  });

  return new Foo();
}



var foo = createFoo();

Object.observe(foo, function (changes) { document.write(changes); });

foo.foo = 'bar';

Why is it that Object.observe's handler is never fired? Can an object prototype be "observed"?

(Please, answers must not suggest to use some kind of third party library.)

Update

Please, read the comments for more information and for the resolution to this problem.

2
  • 1
    Note that the Object.observe proposal was withdrawn: esdiscuss.org/topic/an-update-on-object-observe . Commented Jan 16, 2016 at 5:30
  • Thank you for that. This was an experiment and I was already concerned about speed. Since O.o doesn't work anyway for the use case that I have, I have moved to extending EventEmitter and emitting events instead. I'm choosing the single answer as there is no other answer anyway, so this question can be closed for posterity. Commented Jan 16, 2016 at 5:51

1 Answer 1

2

This

foo.foo = 'bar';

does not modify neither foo object nor its prototype thus observe does not report anything.

Here is the version that triggers observer on this.val = value; :

function createFoo() {
  

  function Foo() {}
  Object.defineProperty(Foo.prototype, 'foo', {
    get: function () {
      return this.val;
    },
    set: function (value) {
      this.val = value; 
      document.write('foo value set to : ', value);
    }
  });

  return new Foo();
}



var foo = createFoo();

Object.observe(foo, function (changes) { document.write("<br>observer:", changes); });

foo.foo = 'bar';

Sign up to request clarification or add additional context in comments.

5 Comments

So... when using a getter/setter, Object.observe won't work, right?
Object.observe triggers on object change. See my update. If your setter modifies the observable object then you will get observe callback notification.
Hrm. however this.val is not the same as the original property name, thus this will set a value to a "random" property name in order to trigger the handler. Sure, it works, however this is just weird. Naturally, replacing this.val with this.foo will just cause an infinite loop...
You define virtual Property that is representing some real or computable property. In first case we usually name virtual and internal properties similarly, like: this._foo = foo;. Not "random" as you said. Object in JS is a name/value map. Modification of this map is a subject of observation, nothing else.
"replacing this.val with this.foo will just cause an infinite loop". Sure as you are getting perfect loop of recursion calls.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.