9

A simple example using a built-in javascript object: navigator.my_new_property = "some value"; //can we detect that this new property was added?

I don't want to constantly poll the object to check for new properties. Is there some type of higher level setter for objects instead of explicitly stating the property to monitor?

Again, I don't want to detect if the property value changed, but rather when a new property is added.

Ideas? thanks

UICodes
  • 141
  • 3

2 Answers2

7

Nope. The existing methods of determining when a property gets written to:

  • an ECMAScript 5 setter defined using defineProperty(obj, name, fn);
  • a legacy JavaScript setter defined using __defineSetter__(name, fn);
  • a legacy Netscape/Mozilla watch(name, fn);

are all name-based, so can't catch a new property being written with a previously-unknown name. In any case, navigator may be a ‘host object’, so you can't rely on any of the normal JavaScript Object interfaces being available on it.

Polling, or explicit setter methods that provide callback, is about all you can do.

Similar situation: Getter/setter on javascript array?

Community
  • 1
  • 1
bobince
  • 498,320
  • 101
  • 621
  • 807
  • Thanks for the detailed response. If I go the polling route, what would you consider to be a good interval in ms? Obviously I would want it to be effective but not repeat unnecessarily. Is there a "standard" interval that some of the frameworks use for their polling? Suggestions are appreciated. – UICodes May 05 '10 at 18:43
  • I think it would depend on exactly what you're aiming to do; there's no one answer. What object are you polling, how often do you expect it to change, how many other properties are defined on it to go through? Whilst you could get away with a very small interval like 50ms on a modern desktop browser, for a well-populated object on a weak browser like IEMobile6 that could bring it to its knees! Incidentally, for the host objects like `navigator` there's not even any guarantee that setting any new properties, or using `for...in` to iterate over them, will work! :-S – bobince May 05 '10 at 19:25
  • you already can't capture property changes on many hosted objects (for instance, try to define a getter/setting on various DOM object properties), so i don't see the problem that providing a general object change notifier would cause. – Michael Jun 28 '14 at 02:24
5

ES6 introduces the concept of Proxies: es6 proxies on MDN.

Here is a simple example:

let objectToSpy = {};
let handler = {
    set: (target, prop, value)=>{
        console.log('new prop:', prop);
        target[prop] = value;
    }
};

let proxy = new Proxy(objectToSpy,handler);
proxy.testProp = 'bla'; //prints: "new prop: testProp"
kundasaba
  • 838
  • 2
  • 11
  • 22
  • This will log on every property change, but adding an additional if-statement will do the job. [Fiddle](https://jsfiddle.net/apt1e1a9/4/) Thank you – dwonisch Mar 07 '18 at 19:42