2012-04-03 7 views
22

Ich möchte den CoffeeScript existential-Operator verwenden, um einige Objekteigenschaften auf undefined zu überprüfen. Ich stieß jedoch auf ein kleines Problem.Wie verwende ich den CoffeeScript existential-Operator, um einige Objekteigenschaften auf undefined zu prüfen?

-Code wie folgt aus:

console.log test if test? 

Compiliert zu:

if (typeof test !== "undefined" && test !== null) console.log(test); 

, die das Verhalten ist, würde ich gerne sehen. Allerdings, wenn ich es gegen Objekteigenschaften versuchen Sie es mit, wie folgt aus:

console.log test.test if test.test? 

ich etwas wie folgt aus:

if (test.test != null) console.log(test.test); 

, die überhaupt wie eine Prüfung gegen undefinierte aussehen desn't. Der einzige Weg, ich das gleiche erreicht haben könnte (1: 1) Verhalten, wie es für Objekte mit war durch eine größere Kontrolle mit:

console.log test.test if typeof test.test != "undefined" and test.test != null 

Die Frage ist - mache ich etwas falsch? Oder ist der kompilierte Code ausreichend, um auf das Vorhandensein einer Eigenschaft zu prüfen (eine Nullprüfung mit Typkonvertierung)?

+0

exaktes Duplikat von [coffeescript nicht null oder undefiniertes Verhalten] (http://stackoverflow.com/questions/20010245/coffeescript-not-null-or-undefined-behavior) – Bergi

+0

@Bergi, diese Frage wurde vor vier Jahren gestellt , der andere - vor zwei Jahren. Ist das andere nicht das Duplikat? :) – Przemek

+1

Richtig, ich fühlte nur, dass der andere die bessere Antwort hatte. Ich schätze, sie sollten zusammengelegt werden. – Bergi

Antwort

44

Dies ist ein gemeinsamer Punkt der Verwechslung mit den existentiellen Betreibern: Manchmal

x? 

kompiliert

typeof test !== "undefined" && test !== null 

und zu anderen Zeiten kompiliert es nur zu

x != null 

Die beiden sind gleichwertig, weilx != nullfalse sein wird, wenn entweder xnull oder undefined ist. So x != null ist eine kompaktere Art und Weise zum Ausdruck (x !== undefined && x !== null). Der Grund für die typeof-Kompilierung ist, dass der Compiler denkt, dass x möglicherweise überhaupt nicht definiert wurde. In diesem Fall würde das Ausführen eines Gleichheitstests ReferenceError: x is not defined auslösen.

In Ihrem speziellen Fall kann test.test den Wert undefined, aber man kann nicht ein ReferenceError durch Bezugnahme auf eine nicht definierte Eigenschaft auf einem vorhandenes Objekt erhalten, so dass der Compiler für die kürzere Ausgabe entscheidet.

+0

Danke! Prägnant und informativ für diejenigen von uns, die Javascript vor Coffeescript vermieden haben :) – Seth

4

Wilde Schätzung; hast du versucht console.log test.test if test?.test??

getestet Gerade mit coffee -p -e 'console.log test.test if test?.test?', die kompiliert:

(function() {

if ((typeof test !== "undefined" && test !== null ? test.test : void 0) != null) { console.log(test.test); }

}).call(this);

+0

Das ist wirklich nützlich, und genau warum bin ich bei dieser Frage gelandet, also stimmt dafür! Macht die if-Aussagen viel prägnanter. – peteski

20

Dieses JavaScript:

a.foo != null 

eigentlich nicht überprüfen, ob die foo Eigenschaft a weder undefined ist noch null.Beachten Sie, dass a.foo? in JavaScript konvertiert wird, das != null statt !== null verwendet. Die Umsätze, die != tut bedeutet, dass diese beiden zutreffen:

null == null 
undefined == null 

Ein einfacher a? wird dies JavaScript:

typeof a !== "undefined" && a !== null 

weil es drei Bedingungen zu überprüfen:

  1. Gibt es ein a in Umfang irgendwo?
  2. Hat a einen Wert von undefined?
  3. Hat a einen Wert von null?

Die erste Bedingung ist wichtig, da nur a != null sagen eine Reference auslösen, wenn es keine a in Umfang ist aber sagen typeof a === 'undefined' nicht. Die typeof Prüfung kümmert sich auch um die a === undefined Bedingung in . Dann können wir es aus mit einem strengen a !== null Test beenden, wie die Pflege von ohne Leistungseinbuße einer unnötigen != nimmt (Anmerkung: != und == sind langsamer als !== und === aufgrund der impliziten Konvertierungen).

Ein wenig lesen, auf welcher != und !== tun könnte fruchtbar sein:

MDN: Comparison Operators


Soweit Ihren Kommentar zu löschen Antwort betrifft, if(a.foo) perfekt gültige Syntax ist wenn Sie die komplette if Anweisung:

if(a.foo) 
    do_interesting_things() 
# or 
do_interesting_things() if(a.foo) 

jedoch if(a.foo) und if(a.foo?) unterscheiden sich darin, wie sie 0, false und '' handhaben.

+0

erstes Ergebnis auf Google; aber tatsächlich! == gibt einen Fehler zurück. könnten wir klären? – Ben

+0

@Ben: Nicht sicher, was Sie meinen, welche Verwendung von '! ==' gibt einen Fehler zurück und was ist der Fehler? –

+0

coffecript-rails (Kaffeescript 2.2.0), "SyntaxError: [stdin]: 37: 38: unerwartet ="; ein schöner 500 Fehler, es kompiliert nur nicht mit einem dritten Zeichen in den Vergleichselementen – Ben

Verwandte Themen