Siehe http://jsperf.com/in-vs-member-object-access
Im Wesentlichen warum ist das Überprüfen von if ('bar' in foo) {}
signifikant langsamer als if (foo.bar !== undefined) {}
?
Siehe http://jsperf.com/in-vs-member-object-access
Im Wesentlichen warum ist das Überprüfen von if ('bar' in foo) {}
signifikant langsamer als if (foo.bar !== undefined) {}
?
foo.bar !== undefined
überprüft nur diese 2 Werte, um festzustellen, ob sie übereinstimmen.
Während 'bar' in foo
einen Mechanismus verwenden muss, um die Eigenschaften von foo
zu durchlaufen und zu sehen, ob bar
darin ist.
Hier ist eine interessante Lektüre von Ecma-Script
Der in-Operator
Die Produktion RelationalExpression: RelationalExpression in ShiftExpression wird wie folgt ausgewertet:
1. Bewertung von RelationalExpression.
2. Aufruf von GetValue(Result(1)).
3. Bewertung von ShiftExpression.
4. Aufruf von GetValue(Result(3)).
5. Wenn Result(4) kein Objekt ist, wird eine TypeError-Ausnahme ausgelöst.
6. Aufruf von ToString(Result(2)).
7. Aufruf der Methode [[HasProperty]] von Result(4) mit dem Parameter Result(6).
8. Rückgabe von Result(7).Der strenge Ungleichheitsoperator ( !== )
============================================
Die Produktion EqualityExpression: EqualityExpression !== RelationalExpression wird wie folgt ausgewertet:
1. Bewertung von EqualityExpression.
2. Aufruf von GetValue(Result(1)).
3. Bewertung von RelationalExpression.
4. Aufruf von GetValue(Result(3)).
5. Durchführung des Vergleichs Result(4) === Result(2). (Siehe unten.)
6. Wenn Result(5) wahr ist, wird false zurückgegeben. Andernfalls wird true zurückgegeben.
Du hast recht. Es macht keinen Sinn, dass "bar" in foo
langsamer ist als foo.bar
.
Der einzige Grund, warum in
nicht genauso schnell ist, ist, dass es nicht so viel Aufmerksamkeit von JIT-Ingenieuren erhalten hat wie die viel häufigere Syntax foo.bar
.
Vor allem im Fall Ihres jsperf-Tests, wo die Eigenschaft als direkte Eigenschaft auf foo
selbst vorhanden ist (nicht als Prototyp), liegt es nahe, dass 'bar' in foo
nicht langsamer sein sollte als foo.bar !== undefined
. Wenn überhaupt, sollte es schneller sein. Der Hauptunterschied zwischen den beiden ist, dass in
beantwortet werden kann, ohne den Wert der Eigenschaft überhaupt zu überprüfen!
Im Fall von foo.bar
erwarte ich, dass sowohl der V8-Motor als auch der SpiderMonkey-Motor erkennen werden, dass der Code nichts Nützliches tut (das heißt, er hat keine beobachtbaren Effekte) und ihn vollständig optimieren werden. Der Benchmark misst keine tatsächliche Arbeit.
Scheinbar sind die Motoren noch nicht klug genug, um "bar" in foo
zu optimieren, aber es ist nur eine Frage der Zeit. Und der Prioritäten.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.