Answer in 2010 : (see 2013 update below)
No, you cannot redirect the search for property names to your own function.
However , with ECMAScript5 you can define properties using "getters" and "seters". This is a new feature that is not yet widely supported, but when it is, it will do something vaguely similar. This is described in several parts of the specification . Therefore, if you defined all your properties this way and then sent the actual request to your central getValue
function, you would end up getting what you wanted. Someday. :-) Except that he does not call getValue
for a property that does not exist.
Answer in 2013 :
This will change soon (and already has one for modern Firefox users): ECMAScript 6th edition will have a proxy. They are defined in the specification as well as on this page (but draft drafts take precedence).
Proxies allow you to create objects that are true proxies (facades) for other objects. Here is a simple example that turns any property values ββthat are strings for all caps upon retrieval:
var original = {"foo": "bar"}; var proxy = new Proxy(original, { get: function(target, name, receiver) { var rv = target[name]; if (typeof rv === "string") { rv = rv.toUpperCase(); } return rv; } }); console.log("original.foo = " + original.foo); // "bar" console.log("proxy.foo = " + proxy.foo); // "BAR"
Live Example | A source
Operations that you do not override have default behavior. In the above example, we all redefine get
, but there is a whole list of operations that you can connect to.
In the argument list of the get
handler function:
target
is an object that is proxied ( original
, in our case).name
is (of course) the name of the returned property.receiver
- either the proxy itself, or something that is inherited from it. In our case, receiver
is ===
proxy
, but if proxy
used as a prototype, receiver
could be a descendant, therefore, it was on the function signature (but at the end, so you can easily refuse it if, as in our example above, you are not actually using it).
This allows you to create an object with the required getter and setter function:
var obj = new Proxy({}, { get: function(target, name) { if (!(name in target)) { console.log("Getting non-existant property '" + name + "'"); return undefined; } return target[name]; }, set: function(target, name, value) { if (!(name in target)) { console.log("Setting non-existant property '" + name + "', initial value: " + value); } target[name] = value; } }); console.log("[before] obj.foo = " + obj.foo); obj.foo = "bar"; console.log("[after] obj.foo = " + obj.foo);
Live Example | Source (notice how I left the receiver
functions since we are not using it. receiver
is an optional fourth argument to arg on set
.)
The conclusion above:
Getting non-existant property 'foo'
[before] obj.foo = undefined
Setting non-existant property 'foo', initial value: bar
[after] obj.foo = bar
Pay attention to how we get the message "nonexistent" when we try to extract foo
when it does not exist yet, and again when we create it, but not afterwards.