Dynamic getters and setters - an opportunity

I am trying to solve a problem that has occurred to me recently. Let's say we would like and would know how to make javascript have dynamic getters and setters, more like php (__get, __set). But since javascript does not have a catch-all property, the only thing we could do is provide a list of possible keys and iteration to add getters and setters only for them, and I hope that no one else comes.

But the problem is far from solved. So the next approach that came to my mind was to use the nasty hack with try and catch , so at any time the name undefined in the object would use catch as a getter (at least) and then resume the code, itโ€™s hard and perhaps a pointless thing. But from here came my second problem, for example:

 console.log(g.someundefinedproperty); 

the result would be a console.log call showing undefined without exception. And then it came to me: what if I use the original window.undefined getter and setter, because it should be called every time I mess up and miss a word or something else.

So i tried

 Object.defineProperty(window, 'undefined', { get : function () { // functional code, including getting the caller and figuring out // where we are, and what we have to do... easy :D console.log('works'); }, set : function () { // some couple more fine hacks here console.log('this too'); } }); 

But, unfortunately, the undefined property of the configurable : false window. Other proven hacks cloned the window object, except for the undefined property and the internal window . And on the new object, define a new undefined (please pay attention to the irony), and then window = mybetterwindow ;

Since this did not cause any problems, my hopes were high, but again the system failed me, because window cannot be overwritten by design. I assumed that it has its own getter, and it is restored based on the prototype found in window.prototype or even better than window.prototype (pay attention to uppercase).

As my last step in this experiment, I redefined undefined on this run prototype. Nothing has changed to no avail ... I tried to create new Window() , but window not a constructor, it does not work!

As my ideas run out, I am here writing this request for help. If you have ideas on how to solve the problem of dynamic getters and setters, ( the existencial problem of life, universe and everything else ), so that it doesnโ€™t change in any way ... the way you use objects (and as a bonus, this no need to break a hole in fabric of time and space ) or syntax, I beg you to speak or be silent forever :).

+7
source share
2 answers

But unfortunately, the undefined property of the configurable: false window configurable: false

This is only true after EcmaScript 5.1 . It used to be rewritable.

what if I used the original window.undefined getter and setter, because it should be called every time I messed up and missed a word or something like that.

No, that would not work. There is a difference between undefined value and the global variable "undefined". A variable is not evaluated every time an undefined value is encountered (for example, in typeof (void 0) ), only if you use it explicitly (for example, in g.someprop === undefined ).

Any ideas how to solve the problem of dynamic getters and setters?

There is only one solution: Proxies . Unfortunately, this is only a harmony project and is currently supported in Firefox Javascript 1.8.5 .

See also Is there an equivalent function __noSuchMethod__ for properties or a way to implement it in JS? Detect when a new property is added to a Javascript object? or How to determine when a property is added to a JavaScript object? in which the polling solution is implemented (checking for changes through setInterval ).

For a clean solution, you need to use the explicit getter function through which you pass the property name ( g.get("someundefinedproperty") ).

+5
source

What you are trying to accomplish (a global getter for any undefined property) goes beyond cross-browser JavaScript.

The closest functionality will be to use __defineGetter__ to add a specific property to all objects:

 var o = Object.prototype; o.__defineGetter__("testo", function() { return "yo in testo"; }); alert({}.testo); alert((new Date()).testo); 

http://jsfiddle.net/NLCvs/2/

This can be useful if you can predict the name in advance possibly undefined. However, this is a pretty hacky and bad form to add access to all objects for a property that may be undefined.

The best option is refactoring code when you can access undefined:

 function getter(o, n) { return typeof o[n] == 'undefined' ? 'some default value' : o[n]; } var obj = { hello: 'world' }; alert(getter(obj, 'hello')); alert(getter(obj, 'an_undefined_property')); 

An even better option is to use mixin to set any default properties you need to get, for example via jQuery.extend

 var defaults = { required: 'this property is required' }; var my_object = { something_else: 'this is something else' }; var o = jQuery.extend({}, defaults, my_object); // o.required === 'this property is required' // o.something_else === 'this is something else' 
+2
source

All Articles