2010-12-10 3 views
4

Wie im Thema JS erwähnt, scheint der gute Teil zu behaupten, dass ein Eigenschaftswert nicht undefiniert sein kann. Allerdings, wenn Sie die folgende in Chrome Konsole zum Beispiel tun:Warum behauptet "Javascript die guten Teile", dass "ein Eigenschaftswert irgendein Javascript-Wert sein kann, außer für undefined"?

var foo = {} 
foo.bar = undefined 
foo 

Klicken Sie dann auf das foo-Objekt erweitern können Sie immer noch sehen, dass foo eine Eigenschaft enthalten, die mit dem Wert genannt bar nicht definiert. Natürlich kann man von der Javascript-Seite aus den Unterschied zwischen foo.bar nicht undefined und foo.unexistingproperty nicht undefiniert erkennen. Aber was ist der Sinn der Konsole, die immer noch an der Eigenschaft festhält, die auf undefiniert gesetzt wurde?

+1

Ich denke, Sie könnten es ein ziemlich nutzloses Chrome "Feature" nennen :) – sje397

+3

@ sje397: Nicht nutzlos. Es besteht ein Unterschied zwischen einer bestehenden und nicht definierten Eigenschaft und einer nicht vorhandenen Eigenschaft. Siehe meine Antwort. –

+0

So wie viele Antworten sagte ich weiß, dass Sie löschen können, um die Eigenschaft loszuwerden und so weiter. Aber die Hauptidee mit meiner Frage war, warum das Buch behauptet, dass der Wert nicht undefiniert sein kann. Offensichtlich scheint dies eine falsche Aussage von Crockford zu sein. – Sam

Antwort

3

undefined ist JavaScript-Art, Ihnen zu sagen, dass ein Wert nicht vorhanden ist, anstatt einen Fehler zu erzeugen, wenn Sie auf die Eigenschaft ohne einen try/catch-Block zugreifen. Obwohl das, was Chrome anzeigt, von Crockfords Konto falsch ist, ist es zumindest logisch; Die Immobilie existiert, wenn auch als undefined.

Wenn Sie eine Eigenschaft entfernen möchten, können Sie die delete operator verwenden:

delete foo.bar; 
+3

Sie erhalten keine Fehlermeldung, wenn Sie versuchen, auf eine nicht definierte Eigenschaft zuzugreifen. Sie erhalten nur einen Fehler, wenn Sie versuchen, auf eine nicht deklarierte Variable zuzugreifen. Und wenn Crockfords Buch sagt, dann ist es Crockford, das ist falsch, nicht Chrome. –

+0

Ich habe nicht gesagt, dass Sie einen Fehler bekommen würden, ich sage nur, dass Javascript 'undefined' als einen alternativen Mechanismus zurückgibt, der einfach einen _Property not found_ Fehler wirft. –

+1

OK. Obwohl JavaScript im Allgemeinen Fehler auslöst, scheint der Zugriff auf eine undefinierte Eigenschaft etwas zu sein, das von JavaScript erwartet wird, und berücksichtigt keinen Fehler. –

4

Technisch undefiniert ist ein gültiger Wert einer Variablen zugewiesen werden soll. Es macht einen Unterschied, wenn auch in der Regel nicht sinnvoll:

var foo = { 
    bar: undefined 
}; 

foo.hasOwnProperty("bar"); // returns true 
foo.hasOwnProperty("bat"); // returns false 

auch:

for (var n in foo) { 
    console.log(n, foo[n]); // should log "bar" and "undefined" 
} 

Ich persönlich würde die von Crockford in diesem Fall gegeben beraten folgen. Die Zuweisung von undefined als Wert kann zu verwirrendem Code führen und sollte daher als schlecht angesehen werden. Es überrascht Leute, die es nicht erwarten.

Wir haben bereits null für diesen Zweck verwenden, die für zukünftige Betreuer weniger verwirrend ist. Lassen Sie undefined wirklich bedeuten nicht definiert und null zu verwenden, um nicht bekannt zu bedeuten.

Denken Sie daran, dass beim Lesen von Crockfords Buch lesen Sie Ratschläge zu Best Practices und Meinung, wie Javascript sollte arbeiten nach ihm. Wie Javascript eigentlich funktioniert ist eine andere Sache insgesamt (und nach ihm nicht unbedingt gut).

+3

Der Kontext, in dem Crockford die Erklärung abgibt, ist nicht ein Rat oder eine Meinung, sondern eine Tatsachenerklärung. Der vollständige Absatz lautet "Ein Objekt ist ein Container mit Eigenschaften, wobei eine Eigenschaft einen Namen und einen Wert hat. Ein Eigenschaftsname kann eine beliebige Zeichenfolge einschließlich der leeren Zeichenfolge sein. Ein Eigenschaftswert kann ein beliebiger JavaScript-Wert außer undefined sein." –

+0

Der Kontext des ganzen Buches ist Crockfords Meinung und Ratschlag, wie man über Javascript nachdenken sollte. Zitat aus dem Buch selbst: "..ich zerreiße die Funktionen, die nicht schön sind ..". Das ganze Buch handelt von Crockfords Meinung über die Fakten, nicht von den Tatsachen an sich. Er gibt zu, dass er nicht daran interessiert ist, Javascript selbst zu beschreiben, sondern stattdessen die Subskripte von Javascript, von denen er denkt, dass sie in erster Linie hätten sein sollen. Wenn Sie ein Buch wünschen, das Javascript beschreibt oder definiert, dann ist das nicht wahr. – slebetman

+0

Ja, Crockford sagt tatsächlich im Vorwort seines Buches: "Ich zerstückle die Eigenschaften, die nicht schön sind ...", um eine Teilmenge von JS aufzudecken, die zuverlässig, lesbar und wartbar ist. Allerdings kann sein Satz über keinen Eigenschaftswert "undefiniert" ist nicht wahr in Chrome und FF, noch scheint es in der Kategorie seiner Meinung zu fallen. Er behält sich die Meinung für die Anhänge des Buches vor. Er schreibt weiter: "Dieses Buch wird nicht versuchen, die Sprache vollständig zu beschreiben. Stattdessen wird es sich auf die guten Teile mit gelegentlicher Warnung konzentrieren, um das Schlechte zu vermeiden". Ich denke, er hat nur einen Fehler in Ch3 gemacht. –

7

Es gibt einen Unterschied zwischen einer bestehenden und nicht definierten Eigenschaft und einer nicht vorhandenen Eigenschaft. Daher ist Chrome hier sinnvoll. Wenn Sie einer Eigenschaft einen Wert zuweisen, ist die Eigenschaft in diesem Objekt grundsätzlich vorhanden. Ein Unterschied besteht darin, dass eine Eigenschaft, die explizit festgelegt wurde nicht definiert werden, werden in einem for...in Schleife zeigen:

var foo = {}; 
foo.bar = undefined; 

// The following will alert "bar" 
for (var i in foo) { 
    alert(i); 
} 

Ein weiterer Grund ist, dass "bar" in footrue zurückkehren wird, ebenso wie foo.hasOwnProperty("bar").

+0

Ich denke, ein nützlicher Nachtrag könnte darin bestehen, die Nützlichkeit der Deklaration von vars für den globalen Geltungsbereich zu erwähnen. Etwas, das Sie abdecken, aber nicht notiert haben (z. B. var a; Funktion doSomething() {a = (a)? 0: 1; return a;} – fncomp

Verwandte Themen