2008-08-26 35 views
26

Code:Javascript của trình duyệt Quirks - array.Length

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>Unusual Array Lengths!</title> 

    <script type="text/javascript"> 
     var arrayList = new Array(); 
     arrayList = [1, 2, 3, 4, 5, ]; 
     alert(arrayList.length); 
    </script> 

</head> 
<body> 
</body> 
</html> 

Chú ý các dấu phẩy trong khai báo mảng. Đoạn mã trên sẽ cho kết quả đầu ra khác nhau cho các trình duyệt khác nhau:

Safari: 5

Firefox: 5

IE: 6

Dấu phẩy thêm trong mảng đã được bỏ qua bởi Safari và FF trong khi IE coi nó như một đối tượng khác trong mảng.

Trên một số tìm kiếm, tôi đã tìm thấy ý kiến ​​khác nhau về câu trả lời nào là chính xác. Hầu hết mọi người nói rằng IE là chính xác nhưng sau đó Safari cũng làm điều tương tự như Firefox. Tôi chưa thử nghiệm điều này trên các trình duyệt khác như Opera nhưng tôi cho rằng có sự khác biệt.

Câu hỏi của tôi:

i. Điều nào là đúng?

Chỉnh sửa: Theo sự đồng thuận chung (và nguyên tắc ECMAScript), chúng tôi giả định rằng IE lại có lỗi.

ii. Có bất kỳ trình duyệt Javascript nào khác mà tôi nên cảnh giác không?

Chỉnh sửa: Có, có vô số câu hỏi Javascript. www.quirksmode.org là một tài nguyên tốt cho cùng.

iii. Làm cách nào để tránh các lỗi như vậy?

Chỉnh sửa: Sử dụng JSLint để xác thực javascript của bạn. Hoặc, sử dụng một số bên ngoài libraries. Hoặc, sanitize mã của bạn.

Nhờ DamienB, JasonBunting, JohnKonrad Rudolph vì những đóng góp của họ.

+2

Cảm ơn bạn, cảm ơn bạn, cảm ơn bạn!!! Một dấu phẩy thừa ngu ngốc đã khiến cho IE8 hoạt động khác với FireFox và nó đang đẩy tôi lên tường cố gắng tìm ra nó! – Tom

+0

Cảm ơn bạn đã đặt câu hỏi này, đã giúp tôi giải quyết vấn đề tôi gặp phải với IE không xử lý một mảng như mong đợi. :) –

+1

Cảm ơn vì điều này. Tôi đã nhận được một lỗi JavaScript IE8 khi tôi kiểm tra .length của một phần tử mảng. Và nguyên nhân là một dấu phẩy phụ trong khai báo mảng. – jamesnotjim

Trả lời

9

Dường như với tôi rằng hành vi của Firefox là chính xác. Giá trị của giá trị thứ 6 trong IE (xin lỗi tôi không có nó tiện dụng để kiểm tra) là gì. Vì không có giá trị thực tế được cung cấp, tôi tưởng tượng nó làm đầy nó với một cái gì đó như 'null' mà chắc chắn không có vẻ là những gì bạn dự định xảy ra khi bạn tạo mảng.

Vào cuối ngày, không thực sự quan trọng là "đúng" vì thực tế là bạn chỉ nhắm mục tiêu một trình duyệt, trong trường hợp này bạn có thể bỏ qua những gì người khác làm hoặc bạn nhắm mục tiêu nhiều trình duyệt trong trường hợp mã của bạn cần phải hoạt động trên tất cả các trình duyệt đó. Trong trường hợp này, giải pháp hiển nhiên là không bao giờ bao gồm dấu phẩy lơ lửng trong bộ khởi tạo mảng.

Nếu bạn gặp sự cố khi tránh sự cố (ví dụ: vì một số lý do bạn đã phát triển thói quen (xấu, imho) bao gồm nó) và các vấn đề khác như thế này, thì có thể là JSLint.

3

"3" cho những trường hợp này, tôi thường đưa vào kịch bản của tôi

if(!arrayList[arrayList.length -1]) arrayList.pop(); 

Bạn có thể làm một chức năng tiện ích ra khỏi đó.

+2

Vì vậy, nếu phần tử cuối cùng là 0 hoặc "" nó sẽ lấy con dao? – mplungjan

+0

Có :-) Tất nhiên, trường hợp đó không bao giờ xảy ra trong tập lệnh của tôi :-) –

+3

if (typeof arrayList [arrayList.length-1] === "undefined") arrayList.pop(); – Tracker1

7

Tôi đã bị cuốn hút vì vậy tôi đã tìm kiếm nó theo định nghĩa ECMAScript 262 ed. 3 là cơ sở của JavaScript 1.8. Định nghĩa liên quan được tìm thấy trong phần 11.1.4 và không may là không rõ ràng. Phần rõ ràng nói rằng các elisions (= bỏ sót) ở đầu hoặc ở giữa không xác định một phần tử nhưng đóng góp vào tổng chiều dài.

Không có báo cáo rõ ràng về dấu phẩy dư thừa ở phần cuối của initializer nhưng do thiếu sót tôi kết luận rằng tuyên bố trên ngụ ý rằng họ làm không đóng góp với tổng thời gian vì vậy tôi kết luận rằng MSIE là sai.

Đoạn liên quan đọc như sau:

phần tử mảng có thể được elided ở phần đầu, giữa hoặc cuối của danh sách phần tử. Bất cứ khi nào dấu phẩy trong danh sách phần tử không có trước Biểu thức chỉ định (tức là dấu phẩy ở đầu hoặc sau dấu phẩy khác), phần tử mảng bị thiếu góp phần vào chiều dài của mảng và tăng chỉ mục của các phần tử tiếp theo. Các phần tử mảng được chọn không được xác định.

+0

Konrad: "Định nghĩa có liên quan được tìm thấy trong phần 11.1.4 và không may là không rõ ràng." Có vẻ như khá rõ ràng đối với tôi: "Bất cứ khi nào dấu phẩy trong danh sách phần tử không được _preceded_ bởi Biểu thức chỉ định [...]". Chỉ khi một biểu thức có trước dấu phẩy bị bỏ qua, nó sẽ được tính là một phần tử ([, foo] => 2 phần tử). Không có đề cập đến biểu hiện thiếu sau dấu phẩy ([foo,] => 1 phần tử). IE có lỗi. – Zuu

+0

Tôi đồng ý rằng nó KHÔNG rõ ràng. Từ định nghĩa sản xuất ArrayLiteral: [ElementList, Elisionopt]: ... Hãy để pad là kết quả của việc đánh giá Elision; nếu không có, hãy sử dụng giá trị số không. ... Gọi phương thức nội bộ [[Đặt]] của mảng với các đối số "độ dài", ToUint32 (pad + len) và sai. ... – Chris

+0

... Với tôi, định nghĩa này nói để đặt độ dài cho chiều dài của hình elip (pad) cộng với độ dài của danh sách phần tử trước đó. Nếu đây không phải là cách tôi phải đọc nó, ai đó hãy khai sáng cho tôi. – Chris

0

@John: Giá trị của arrayList [5] trở thành 'không xác định'.

Có, không bao giờ có dấu phẩy lơ lửng trong các khai báo. Trên thực tế, tôi đã chỉ đi qua mã javascript dài của người khác mà bằng cách nào đó đã không làm việc một cách chính xác trong browers khác nhau. Hóa ra rằng dấu phẩy lơ lửng là thủ phạm đã vô tình bị gõ vào! :)

2

Trước hết, Konrad là quyền trích dẫn thông số, vì đó là điều xác định ngôn ngữ và trả lời câu hỏi đầu tiên của bạn.

Để trả lời các câu hỏi khác của bạn:

Có bất kỳ trình duyệt javascript ví dụ khác quirks mà tôi cần phải cảnh giác với?

Ồ, quá nhiều để liệt kê ở đây! Hãy thử the QuirksMode website để tìm một địa điểm tốt để tìm gần như mọi thứ đã biết.

Làm cách nào để tránh các lỗi như vậy?

Cách tốt nhất là sử dụng a library để tóm tắt những vấn đề này cho bạn để bạn có thể lo lắng về logic của ứng dụng. Mặc dù một chút bí truyền, tôi thích và khuyên bạn nên MochiKit.

1

Điều nào sau đây là đúng?

Opera cũng trả về 5. Điều đó có nghĩa là IE đông hơn và đa số quy tắc theo như bạn mong đợi.

1

Ecma 262 edition 5.1 phần 11.1.4 bộ khởi tạo mảng cho biết dấu phẩy ở cuối nếu mảng không đóng góp độ dài nếu mảng đó. "Nếu một phần tử được elided vào cuối mảng nó không góp phần vào độ dài của mảng"

Điều đó có nghĩa [ "x",] là hoàn toàn hợp pháp javascript và cần trả về một mảng có độ dài 1

+0

Không có sự mơ hồ về nó, nó là khá rõ ràng trong spec, trong đó nói rõ rằng 'nếu một yếu tố được elided' [tức là bỏ qua] 'ở phần cuối của mảng nó không góp phần chiều dài của mảng' - nó không thể nào rõ ràng hơn –

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