2009-11-19 19 views

Trả lời

12

Theo đặc tả ES3, họ là hơi khác nhau ở chỗ cú pháp chữ (/regex/) sẽ tạo ra một đối tượng RegExp đơn khi quá trình quét ban đầu:

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 thành đối tượng RegExp (phần 15.10) khi quét . Đối tượng được tạo trước khi đánh giá chương trình hoặc chức năng có chứa bắt đầu. Đánh giá của nghĩa đen tạo ra một tham chiếu đến đối tượng đó; nó không tạo đối tượng mới.

Các lỗi trong spec đã được thừa nhận trong ES4:

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

Triển khai khác nhau giữa các trình duyệt. Safari và IE xử lý các chữ theo ES4, nhưng Firefox và Chrome xuất hiện để xử lý chúng theo ES3.

Hãy thử đoạn mã sau trong các trình duyệt khác nhau và bạn sẽ thấy những gì tôi có nghĩa là:

function f() { 
    return /abc/g.test('abc'); 
} 

alert(f()); // Alerts true 
alert(f()); // Alerts false in FF/Chrome 

So với:

function f() { 
    return RegExp('abc', 'g').test('abc'); 
} 

alert(f()); // Alerts true 
alert(f()); // Alerts true 

Note, giả được cảnh báo bởi vì chức năng vẫn sử dụng regex từ cuộc gọi trước đó của hàm đó, số lastIndex đã được cập nhật, có nghĩa là nó sẽ không khớp với chuỗi "abc" nữa.


Mẹo: nhà cung cấp new không được yêu cầu cho RegExp để được khởi tạo. RegExp() bởi chính nó hoạt động giống ...


Thông tin thêm về/4 vấn đề ES3: Regex/lastIndex - Unexpected behaviour

+0

Đó là điều thú vị, con người. Đó là điều thú vị. –

+0

Vì vậy, bạn có thể tranh luận rằng việc sử dụng biểu mẫu nội tuyến sẽ hiệu quả hơn một chút (ít nhất là trong ES3). Trong khi biểu mẫu RegExp sẽ tạo ra kết quả thực thi chéo nhất quán hơn. Tuyệt vời! –

+0

+1 tìm/trả lời tốt – cletus

2

Theo J-P's answer một sự khác biệt nhỏ, đôi khi có thể quan trọng. Các ý định là:

var re = /\d+/; 

được giống như:

var re = new RegExp("\\d+"); 

nhưng, kỳ quặc, trong Firefox/Chrome nó không phải là khá như nhau (như chứng minh bằng ví dụ của mình với các biểu thức trạng thái được sử dụng nhiều lần).

Vì vậy, hãy sử dụng đối tượng RegExp sẽ là lời khuyên của tôi. Và một tìm kiếm tuyệt vời của J-P.

Điều đó đang được nói, bối cảnh chính nơi bạn phải sử dụng RegExp so với cú pháp theo nghĩa đen nào là để tự động tạo ra các biểu thức, ví dụ:

var s = "[asdf]+"; 
var re = new RegExp(":" + s + ":", "g"); 
+2

Có phải là người ngồi khác biệt rõ hơn. Động lực của tôi cho việc đặt câu hỏi này là bởi vì JSLint dường như không thích định dạng nội tuyến. Thật không may tôi không thể tìm thấy một lý do dễ hiểu là tại sao. –

+2

JSLint không thích nhiều thứ hầu như giống hệt nhau. Hãy nhớ rằng JSLint là một bộ kiểm tra * style *, không chỉ là một trình kiểm tra cú pháp. Nó rất có thể cau mày bởi ông Crockford bởi vì nó có thể khó hiểu hoặc một cái gì đó tương tự. – nickf

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