admin管理员组文章数量:1405512
I am trying to solve a problem that came to my mind lately. Let's say we would want and would know how to make a point in having dynamic getters and setters in javascript, more like those in php (__get, __set). But as javascript does not have a catch-all property the only thing we could do is to provide a list of possible keys and iterate to add getters and setters on those only, and hope none other will ever e.
But the problem is not by far solved. So the next approach that came to my mind was to use a nasty hack with try
and catch
, so anytime a name would be undefined in an object to use the catch
as a getter (at least) and then resume the code, hard and maybe pointless thing to do. But from here came my second problem, in an use such as this :
console.log(g.someundefinedproperty);
the result would have been a call to console.log
showing undefined
with no exception to be ever thrown.
And then it came to me: what if I would use the original window.undefined
getter and setter, after all it must be called every time I screw up and misspell a word or something.
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 window is configurable : false
.
Other hacks tried were cloning the window
object except the undefined
and the inner window
property. And on the new object to define the new undefined
(please take note of the irony) and then window = mybetterwindow
;
As this did not rose any issue my hopes were high, but yet again the system failed me as window
can't be overwritten, by design.
I made a guess it has it's own getter and it's reinstanciate itself based on the prototype found in window.prototype
or even better Window.prototype
(note the uppercase).
As my final step in this experiment I had redefined undefined
on this prototype hitted run. To no avail, nothing was changed... I tryed creating a new Window()
, but Window
is not a constructor, fail!
As I have run out of ideas I find myself here writing this pleading for help.
If you have any ideas how to solve the dynamic getters and setters problem, (the existencial problem of life, universe and everything else
), in a way which does not modify in any way the... way I use the objects (and as bonus it doesn't need to break
a hole
in the fabric of time and space
) or the syntax, I entreat you to speak or forever be silent :).
I am trying to solve a problem that came to my mind lately. Let's say we would want and would know how to make a point in having dynamic getters and setters in javascript, more like those in php (__get, __set). But as javascript does not have a catch-all property the only thing we could do is to provide a list of possible keys and iterate to add getters and setters on those only, and hope none other will ever e.
But the problem is not by far solved. So the next approach that came to my mind was to use a nasty hack with try
and catch
, so anytime a name would be undefined in an object to use the catch
as a getter (at least) and then resume the code, hard and maybe pointless thing to do. But from here came my second problem, in an use such as this :
console.log(g.someundefinedproperty);
the result would have been a call to console.log
showing undefined
with no exception to be ever thrown.
And then it came to me: what if I would use the original window.undefined
getter and setter, after all it must be called every time I screw up and misspell a word or something.
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 window is configurable : false
.
Other hacks tried were cloning the window
object except the undefined
and the inner window
property. And on the new object to define the new undefined
(please take note of the irony) and then window = mybetterwindow
;
As this did not rose any issue my hopes were high, but yet again the system failed me as window
can't be overwritten, by design.
I made a guess it has it's own getter and it's reinstanciate itself based on the prototype found in window.prototype
or even better Window.prototype
(note the uppercase).
As my final step in this experiment I had redefined undefined
on this prototype hitted run. To no avail, nothing was changed... I tryed creating a new Window()
, but Window
is not a constructor, fail!
As I have run out of ideas I find myself here writing this pleading for help.
If you have any ideas how to solve the dynamic getters and setters problem, (the existencial problem of life, universe and everything else
), in a way which does not modify in any way the... way I use the objects (and as bonus it doesn't need to break
a hole
in the fabric of time and space
) or the syntax, I entreat you to speak or forever be silent :).
- Do you have a real life problem you're trying to solve? – Ash Burlaczenko Commented Dec 12, 2012 at 22:15
-
I think redefining
undefined
does risk breaking a hole in the fabric of time and space. Maybe that's why it's been forbidden in ES5. This is an interesting question, however I foresee most answers and ments will be telling you that catch-all accessors are not needed, and harmful. Heck, you're even citing PHP as an example! :P – bfavaretto Commented Dec 12, 2012 at 22:15 - Of course I do, no point in here if I wouldn't have. It's the design I must follow for the framework I am working on. – helly0d Commented Dec 12, 2012 at 22:16
- 3 The only way to do what you want, is using ECMAScript 6 Proxies, they are usable on modern engines (IIRC, they are available on FF4+ and Chrome 19+). See also: stackoverflow./questions/2266789/… – Christian C. Salvadó Commented Dec 12, 2012 at 22:28
- 1 @helly0d Yeah, god do know you tried :D. I am also very interested in this issue. – khael Commented Dec 12, 2012 at 22:33
2 Answers
Reset to default 5But unfortunately the undefined property of window is
configurable: false
This is true only since EcmaScript 5.1. Before, it was overwritable.
what if I would use the original
window.undefined
getter and setter, after all it must be called every time I screw up and misspell a word or something.
No, it would not have worked. There is a difference between the undefined value and the global variable "undefined". The variable is not evaluated each time a undefined value is encountered (e.g. in typeof (void 0)
), only when you use it explicitly (such as in g.someprop === undefined
).
Any ideas how to solve the dynamic getters and setters problem?
There is only one solution: Proxies
. Unfortunately, it is only a harmony draft and currently only supported in Firefox' Javascript 1.8.5.
See also Is there an equivalent of the __noSuchMethod__ feature for properties, or a way to implement it in JS?, Detect when a new property is added to a Javascript object? or How to detect when a property is added to a JavaScript object? which implements a polling solution (checking for changes via setInterval
).
For a clean solution, you currently have to use an explicit getter function, which you pass the property name (g.get("someundefinedproperty")
).
What you're trying to acplish (a global getter for any undefined property) is outside the scope of cross-browser JavaScript.
The closest functionality would be using __defineGetter__
to add a particular property to all objects:
var o = Object.prototype;
o.__defineGetter__("testo", function() { return "yo in testo"; });
alert({}.testo);
alert((new Date()).testo);
http://jsfiddle/NLCvs/2/
This may be useful if you can predict the name of possibly undefined properties ahead of time. Even so it's quite hacky and bad form to add an accessor to all objects for a property that might be undefined.
A better option is to refactor code when an undefined property may be accessed:
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 a mixin to set any default properties you will need to access, for instance 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'
本文标签: javascriptdynamic getter and settersa possibilityStack Overflow
版权声明:本文标题:javascript - dynamic getter and setters - a possibility - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744920963a2632289.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论