2009-08-25 7 views
9

Grundsätzlich geht es in meiner Frage darum, wie Javascript mit Regex-Literalen umgeht.Sind/Regex/Literale immer RegExp Objekte?

Im Gegensatz zu Zahl, String und Boolean, wo Literale primitive Datentypen sind und entsprechende Number-, String- und Boolean-Objekte mit Seamless-Typkonvertierung existieren, sind Regex-Literale anonyme Instanzen des RegExp-Objekts oder ist dies ein Fall von Regex, der behandelt wird primitive Daten mit nahtloser Typkonvertierung in RegExp?

"Die komplette Referenz Javascript, 2. Ausgabe, Powell und Schneider (MH)" widerspricht sich selbst - an einer Stelle sagen die Autoren, dass/regex/wird automatisch in RegExp bei Bedarf eingetippt und an anderer Stelle sagen sie/regex/ist nichts als eine Instanz von RegExp!

EDIT: Bitte geben Sie einen Verweis auf eine zuverlässige Quelle

Antwort

12

Hier ist, was the spec zu sagen hat:

Ein regulärer Ausdruck wörtlichen ist ein Eingabeelement, das auf ein RegExp-Objekt umgewandelt wird, wenn es abgetastet wird. Das Objekt wird erstellt, bevor die Auswertung des enthaltenen Programms oder der Funktion beginnt. Die Auswertung des Literals erzeugt eine Referenz auf dieses Objekt; Es erstellt kein neues Objekt. Zwei Literale mit regulärem Ausdruck in einem Programm werten Objekte mit regulärem Ausdruck aus, die sich niemals als === miteinander vergleichen, selbst wenn der Inhalt der beiden Literale identisch ist.

Es gibt keine primitive regex Typ, der in der gleichen Weise wie string oder number zu einem Objekt Autoboxen.

Beachten Sie jedoch, dass nicht alle Browser das "Instantiate-Once-per-Literal" -Verhalten implementieren, einschließlich Safari und IE6 (und möglicherweise später), so dass portabler Code nicht davon abhängen sollte. Der gescheiterte ECMAScript 4 Entwurf would have changed the behavior diesen Browser entsprechen:

In ES3 einen regulären Ausdruck wörtlicher wie /a*b/mg bezeichnet ein einziges eindeutiges RegExp-Objekt, das zum ersten Mal erstellt wird, die wörtlichen bei der Auswertung festgestellt wird. In ES4 wird jedes Mal ein neues RegExp-Objekt erstellt, wenn das Literal während der Auswertung gefunden wird.

Auch einige Browser (Firefox <3, Safari) berichten typeof /regex/ als "function", so portablen Code typeof auf RegExp Instanzen-Stick mit instanceof vermeiden sollte.

+0

Bleib nicht bei instanceof. Bleib bei [[Class]] checking (http: // thinkweb2.com/projects/prototype/instanceof-discovered-harmful-or-how-to-write-a-robust-isarray/) – kangax

+0

Aktualisierter Link http://perfectionkills.com/instanceof-sidered-harmful-or-how- to-write-a-robust-isarray/ –

+0

@FabioBeltramini der aktualisierte Link ist kaputt –

1

Ja, neue RegExp ("etwas", "g") ist die gleiche wie /etwas/g

+0

Nicht genau, in Bezug auf Sonderzeichen und Flucht. Mit einem Regex-Literal, um eine einzelne Rücktaste zu erreichen, tun Sie '/ \\ /'; Mit dem Konstruktor brauchen Sie '" \\\\ "'. – Miles

+0

Das ist, weil der Konstruktor ein Zeichenfolgenargument erfordert, aber Regexliterale ihre eigene Syntax haben. Dies beantwortet jedoch nicht die Frage :( –

+1

@Miles: aber am Ende erhalten Sie Instanz von RegExp in beiden Fällen. Die Frage war nicht "welcher Syntaxunterschied zwischen diesen beiden Fällen". – Kamarey

6

Ja, die folgenden zwei Ausdrücke sind äquivalent:

var r1 = /ab+c/i, 
    r2 =new RegExp("ab+c", "i"); 

der Konstruktor Eigenschaft der beiden Punkte zum RegExp -Konstruktorfunktion:

(/ab+c/i).constructor === RegExp // true 
r2.constructor === RegExp // true 

Und ein regexp wörtlichen ist eine Instanz RegExp:

/ab+c/i instanceof RegExp // true 

Der grundlegende Unterschied besteht darin, dass mit der Konstruktorfunktion reguläre Ausdrücke definieren Sie einen Ausdruck aus einem String bauen und kompilieren können. Dies kann sehr nützlich sein, um komplexe Ausdrücke zu konstruieren, die wiederverwendet werden.

+0

Sie sind richtig, aber die Tatsache, dass die constructor property points auf RegExp belegt eigentlich nichts. "foo" .constructor === String wird auch als true ausgewertet. –