2009-08-25 32 views
9

Về cơ bản, câu hỏi của tôi là về cách Javascript xử lý các ký tự regex.Are/regex/Literals luôn là đối tượng RegExp?

Tương phản với số, chuỗi và boolean nơi chữ cái là kiểu dữ liệu nguyên thủy và các đối tượng Số, Chuỗi và Boolean tương ứng với chuyển đổi loại liền mạch, là các trường hợp ẩn danh regex literals của đối tượng RegExp hoặc đây là trường hợp regex được xử lý như dữ liệu nguyên thủy với chuyển đổi kiểu liền mạch sang RegExp?

"Javascript tham chiếu đầy đủ, ấn bản thứ 2, Powell và Schneider (MH)" mâu thuẫn - tại một nơi tác giả nói rằng/regex/được tự động nhập vào RegExp khi cần thiết và ở nơi khác họ nói rằng/regex/chẳng là gì ngoài một thể hiện của RegExp!

EDIT: Vui lòng cung cấp một tham chiếu đến một nguồn đáng tin cậy

Trả lời

12

Đây là những gì the spec đã nói:

Một biểu thức chính quy theo nghĩa đen là một yếu tố đầu vào được chuyển đổi sang một đối tượng RegExp khi nó được quét. Đối tượng được tạo trước khi đánh giá chương trình hoặc chức năng chứa bắt đầu. Đánh giá của chữ tạo ra một tham chiếu đến đối tượng đó; nó không tạo ra một đối tượng mới. Hai cụm từ biểu thức chính quy trong một chương trình đánh giá các đối tượng biểu thức chính quy không bao giờ so sánh với nhau là === với nhau ngay cả khi nội dung của hai chữ cái giống hệt nhau.

Không có loại regex nguyên thủy tự động chuyển đến đối tượng theo cùng cách như string hoặc number. Tuy nhiên, lưu ý rằng không phải tất cả các trình duyệt đều thực hiện hành vi "instantiate-once-per-literal", bao gồm Safari và IE6 (và có thể sau này), vì vậy mã di động không nên phụ thuộc vào nó. Các thất bại ECMAScript 4 dự thảo would have changed the behavior để phù hợp với những trình duyệt:

Trong ES3 một biểu thức chính quy theo nghĩa đen như /a*b/mg biểu thị một đối tượng RegExp độc đáo duy nhất được tạo ra lần đầu tiên theo nghĩa đen là gặp phải trong quá trình đánh giá. Trong ES4, một đối tượng RegExp mới được tạo ra mỗi lần gặp phải chữ trong quá trình đánh giá.

Ngoài ra, một số trình duyệt (Firefox <3, Safari) báo cáo typeof /regex/ như "function", do đó, mã di động nên tránh typeof trên RegExp trường hợp dính với instanceof.

+0

Không gắn bó với 'instanceof'. Stick với kiểm tra [[Class]] (http: // thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/) – kangax

+0

Cập nhật liên kết http://perfectionkills.com/instanceof-considered-harmful-or-how- to-write-a-strong-isarray/ –

+0

@FabioBeltramini liên kết cập nhật bị hỏng –

1

Vâng, RegExp mới ("cái gì đó", "g") cũng giống như /cái gì/g

+0

Không chính xác, liên quan đến các ký tự đặc biệt và thoát. Với một regex chữ, để phù hợp với một backspace duy nhất, bạn làm '/ \\ /'; với hàm tạo, bạn cần '" \\\\ "'. – Miles

+0

Đó là vì hàm tạo yêu cầu đối số chuỗi nhưng các ký tự regex có cú pháp riêng của chúng. Điều này không trả lời câu hỏi mặc dù: ( –

+1

@Miles: nhưng cuối cùng bạn nhận được ví dụ của RegExp trong cả hai trường hợp. Câu hỏi không phải là "sự khác biệt cú pháp giữa hai trường hợp này". – Kamarey

6

Có, sau hai biểu thức là tương đương:

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

thuộc tính constructor của cả hai điểm đến chức năng RegExp constructor:

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

Và một regexp đen là một thể hiện của RegExp:

/ab+c/i instanceof RegExp // true 

Sự khác biệt cơ bản là xác định biểu thức thông thường bằng cách sử dụng chức năng xây dựng cho phép bạn xây dựng và biên dịch một biểu hiện từ một chuỗi. Điều này có thể rất hữu ích cho việc xây dựng các biểu thức phức tạp sẽ được sử dụng lại.

+0

Bạn là chính xác, nhưng thực tế là các điểm đặc tính của hàm xây dựng cho RegExp không thực sự chứng minh bất cứ điều gì. "foo" .constructor === String cũng đánh giá là đúng. –

Các vấn đề liên quan