Antwort 2010: (unten für ein 2013-Update sehen)
Nein, Sie können nicht Eigenschaftsnamen Lookups auf Ihre eigene Funktion umleiten.
Jedoch, ab ECMAScript5 können Sie Eigenschaften mit "Getters" und "Setter" definieren. Dies ist ein neues Feature, das noch nicht weit verbreitet ist, aber wenn es ist, wird es etwas tun vage ähnlich. Dies ist in einigen Teilen von the spec abgedeckt. Wenn Sie also alle Ihre Eigenschaften auf diese Weise definiert haben und dann die eigentliche Anfrage an Ihre zentrale getValue
-Funktion gesendet haben, würden Sie weitgehend das erreichen, was Sie wollten. Irgendwann mal. :-) Außer dass es nicht getValue
für eine Eigenschaft aufrufen wird, die nicht existiert.
Antwort im Jahr 2013:
Das wird sich bald ändern (und es already has für up-to-date Firefox-Benutzer): ECMAScript 6. Auflage wird Proxies haben. Sie sind in der draft specification und auch auf this page definiert (aber die Spezifikationen Entwürfe haben Vorrang).
Mithilfe von Proxies können Sie Objekte erstellen, bei denen es sich um echte Proxies (Fassaden) für andere Objekte handelt. Hier ist ein einfaches Beispiel, das keinen Eigenschaftswert stellt sich die Strings für alle Kappen auf Abruf ist:
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 | Source
Operationen, die Sie nicht überschreiben, haben ihr Standardverhalten. Im obigen Beispiel überschreiben wir nur get
, aber es gibt eine ganze Liste von Operationen, in die Sie sich einklinken können.
In der get
Argumente Liste der Handler-Funktion:
target
ist das Objekt proxied wird (original
, in unserem Fall).
name
ist (natürlich) der Name der Eigenschaft, die abgerufen wird.
receiver
ist entweder der Proxy selbst oder etwas, das davon erbt.In unserem Fall ist ===
proxy
, aber wenn proxy
als Prototyp verwendet wurde, könnte ein nachkommendes Objekt sein, daher ist es auf der Funktionssignatur (aber am Ende, so können Sie es leicht auslassen, wenn, wie bei unseren Beispiel oben verwenden Sie es nicht wirklich).
Auf diese Weise können Sie ein Objekt mit dem Catch-All erstellen Getter und Setter-Funktion, die Sie wollen:
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(Beachten Sie, wie ich receiver
von den Funktionen verlassen haben, da wir es nicht verwenden receiver
auf set
eine optionale vierte arg..)
Der Ausgang des oben ist:
Getting non-existant property 'foo'
[before] obj.foo = undefined
Setting non-existant property 'foo', initial value: bar
[after] obj.foo = bar
Beachten Sie, wie wir die "nicht existierende" Nachricht erhalten, wenn wir versuchen, foo
abzurufen, wenn es noch nicht existiert, und wieder, wenn wir es erstellen, aber nicht danach.
FYI wie diese mit ein wenig regexp getan werden, die Dinge haben sich geändert, seit die Frage gestellt wurde. Ich habe [meine Antwort aktualisiert] (http://stackoverflow.com/a/4569315/157247). –