2012-05-23 3 views
8

Grundsätzlich muss ich in der Lage sein, dies zu tun:definieren Getter auf Objekt so alle nicht definierte Eigenschaft Lookups return „“

var obj = {"foo":"bar"}, 
    arr = []; 
with(obj){ 
    arr.push(foo); 
    arr.push(notDefinedOnObj); // fails with 'ReferenceError: notDefinedOnObj is not defined' 
} 
console.log(arr); // ["bar", ""] <- this is what it should be. 

Ich bin auf der Suche nach einem „global“ Äquivalent {}.__defineGetter__ oder {get}, um zurückzukehren eine leere Zeichenfolge für alle nicht definierten Eigenschaftengetter (beachten Sie, dass dies eine andere Eigenschaft als undefined ist).

+0

Können Sie verwenden, um einen [Proxy] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Proxy)? – thisgeek

+0

Es sieht nicht so aus, als wäre 'Proxy' in irgendeiner Knotenversion verfügbar. :-( –

+0

Yeah. Sieht so aus, als wäre V8 [arbeitet noch daran] (http://code.google.com/p/v8/issues/detail?id=1543). – thisgeek

Antwort

7

Sie ein Proxy erstellen eine leere Zeichenfolge, wenn nicht definierte Eigenschaften zurückzukehren zugegriffen werden.

app.js:

var obj = {"foo":"bar"}, 
    arr = [], 
    p = Proxy.create({ 
     get: function(proxy, name) { 
      return obj[name] === undefined ? '' : obj[name]; 
     } 
    }); 
arr.push(p.foo); 
arr.push(p.notDefinedOnObj); 

console.log(arr); 

Als Frage Autor David Murdoch stellt fest, wenn Sie Knoten v0.6.18 verwenden (die letzte Version zum Zeitpunkt dieser Beitrag geschrieben wurde), müssen Sie die Option --harmony_proxies geben, wenn Sie führen Sie das Skript:

$ node --harmony_proxies app.js 
[ 'bar', '' ] 

Beachten Sie, dass diese Lösung nicht Arbeit, wenn Sie with verwenden, wie in:

var obj = {"foo":"bar"}, 
    arr = [], 
    p = Proxy.create({ 
     get: function(proxy, name) { 
      return obj[name] === undefined ? '' : obj[name]; 
     } 
    }); 
with (p) { 
    arr.push(foo); // ReferenceError: foo is not defined 
    arr.push(notDefinedOnObj); 
} 

console.log(arr); 

with scheint die get-Methode des Proxys nicht aufzurufen, wenn der Proxy der Bereichskette hinzugefügt wird.

Hinweis: Der in diesem Beispiel an Proxy.create() übergebene Proxy-Handler ist unvollständig. Weitere Informationen finden Sie unter Proxy: Common mistakes and misunderstanding.

+1

Die verschiedenen Proxy-Implementierungen sind überall. Proxy in 0.6.x funktioniert einfach nicht, wenn Sie den Proxy tatsächlich weitergeben möchten. In 0.7.8 existiert 'Object.getPropertyDescriptor' nicht, obwohl die Methode' getPropertyDescriptor' auf dem Proxy benötigt wird und beim Aufrufen einer nicht existierenden Eigenschaft aufgerufen wird (Sie können es mit 'Object.get * vortäuschen) * Eigener ** PropertyDescriptor' stattdessen). –

+1

Ich habe festgestellt, dass [Node-Proxy] (https://github.com/samshull/node-proxy) (kompiliert jetzt nicht unter Windows, nimm 'node-proxy.bin' von [hier]) (http://blog.nowjs.com/running-nowjs-natively-on-windows)) FUNKTIONIERT auf v 0.6.x OHNE spezielle Befehlszeilen-Flags. Sie müssen jedoch 'true' von der' hasOwn'-Methode auf dem Proxy zurückgeben, nicht 'getPropertyDescriptor'. Das bedeutet leider, dass 'if ((name in obj))' checks IMMER True zurückgeben. –

3

Es gibt keinen globalen fehlenden Memberhandler in Javascript. Sie müssen eine Funktion zu abstrahieren aus dem Verhalten einzuführen

function getOrEmpty(obj, name) { 
    if (!obj.hasOwnProperty(name)) { 
    return ""; 
    } 
    return obj[name]; 
} 

var obj = {"foo":"bar"}, 
    arr = []; 
arr.push(getOrEmpty(obj, "foo")); 
arr.push(getOrEmpty(obj, "someUndefinedProperty")); 
console.log(arr); 
+0

Richtig, aber der Code, der ausgeführt wird, ist benutzergeneriert (aus einer Vorlage). Außerdem müsste die" getOrEmpty "-Funktion" Object.prototype.hasOwnProperty "aufrufen .call (obj, name) 'anstatt den Wert der Eigenschaft selbst gegen undefined zu prüfen. Ein' undefinierter' * Wert * könnte gemeint sein. –

+0

ps, ​​schlug ich vor, den Prototyp 'hasOwnProperty' anstelle von' obj' zu verwenden, weil Wenn 'obj' irgendwie eine' hasOwnProperty' Eigenschaft erhält, wird der Aufruf ausgeführt Scheitern. Ich weiß, dass dies im gegebenen Beispiel nicht passieren kann, aber es ist eine gute Sache, darauf zu achten. –

+0

@DavidMurdoch Ich dachte, das ist der Grund, warum du es vorgeschlagen hast. Aber wenn JavaScript-Code beginnt, vordefinierte Mitglieder zu ersetzen, sind Sie im Grunde sowieso geschraubt. Nicht zu sagen, was sie in die Luft jagten. – JaredPar

0

Mit ES6 und höher können Sie Proxy verwenden, wie die angenommene Antwort vorgeschlagen. Aber hier ist eine Antwort, wenn Sie mit ES5 feststecken.

Mit ES5 Sie Ihre eigene Klasse erstellen müssen, wie in diesem Beispiel schnell

function StrictObject() { 
    var values = Object.create(null); 
    this.set = function (key, value) { 
    values[key] = value; 
    }; 
    this.get = function (key) { 
    if (!(key in values)) { 
     throw new Error("Could not find " + key); 
    } 
    return values[key]; 
    }; 
} 
var obj = new StrictObject(); 

obj.set('dad', 'homer'); 
console.log(obj.get('dad')); // homer 
console.log(obj.get('uncle')); // throws error 
Verwandte Themen