Tôi hơi muộn câu hỏi nhưng tôi nghĩ tôi có thể đưa ra câu trả lời hay.
Câu trả lời được chấp nhận không cho bạn biết thêm bất kỳ điều gì bạn thực sự biết và đề cập đến trong câu hỏi: Number(value)
hoạt động như +value
nhưng không phải là parseInt(value)
.
Điều quan trọng là phải biết rằng có một sự khác biệt ngữ nghĩa giữa loại chuyển đổi và phân tích.
Tại sao chuỗi số bát phân được đúc dưới dạng số thập phân?
Vì Number constructor called as a Function (Number(value)
) và Unary +
Operator (+value
) đằng sau hậu trường sử dụng các hoạt động nội bộ ToNumber
. Mục đích của các cấu trúc đó là loại chuyển đổi.
Khi ToNumber
is applied to the String Type một sản xuất ngữ pháp đặc biệt được sử dụng, được gọi là StringNumericLiteral
.
sản xuất này có thể giữ literals chỉ Decimal và literals Hexadecimal Integer:
...
StrNumericLiteral :::
StrDecimalLiteral
HexIntegerLiteral
...
Ngoài ra còn có sự khác biệt về ngữ nghĩa giữa ngữ pháp này và ngữ pháp của "bình thường" NumericLiterals
.
Một StringNumericLiteral
:
- Có thể trước và/hoặc sau khoảng trắng và/hoặc Terminators dòng.
- Đó là số thập phân có thể có bất kỳ số 0 chữ số hàng đầu nào. không có octals!
- Đó là số thập phân có thể đứng trước dấu + hoặc - để biểu thị ký hiệu của nó.
- Trống hoặc chỉ chứa khoảng trắng được chuyển thành +0.
Bây giờ tôi sẽ đi với các chức năng parseInt
và parseFloat
.
Mục đích của những chức năng rõ ràng là phân tích, đó là ngữ nghĩa khác nhau để loại chuyển đổi, ví dụ:
parseInt("20px"); // 20
parseInt("10100", 2); // 20
parseFloat("3.5GB"); // 3.5
// etc..
là đáng nói rằng các thuật toán của parseInt
thay đổi trong 5 ECMAScript Đặc tả Phiên bản, nó không còn diễn giải một số của radix dưới dạng bát phân chỉ để có số 0 đứng đầu:
parseInt("010"); // 10, ECMAScript 5 behavior
parseInt("010"); // 8, ECMAScript 3 behavior
Như bạn thấy, đã giới thiệu một incompatibility trong hành vi giữa triển khai ES3 và ES5, và như mọi khi được khuyến nghị sử dụng đối số gốc, để tránh bất kỳ vấn đề nào có thể xảy ra.
Bây giờ câu hỏi thứ hai của bạn:
Tại sao chữ bát phân được giảm từ ECMAScript 5th Edition trong chế độ nghiêm ngặt?
Trên thực tế, nỗ lực này của cách loại bỏ các chữ bát phân đến kể từ năm 1999. Các tác phẩm văn chương bát phân (OctalIntegerLiteral
và OctalEscapeSequence
) đã được gỡ bỏ từ ngữ pháp của NumericLiteral
s kể từ khi ECMAScript 3rd Edition specification, họ thể được bao gồm cho backwards compatibility (also in ES5) với các phiên bản tiêu chuẩn cũ hơn. Trên thực tế, chúng được bao gồm trong tất cả các triển khai chính, nhưng về mặt kỹ thuật, việc triển khai tuân thủ ES3 hoặc ES5 có thể chọn không bao gồm chúng, vì chúng được mô tả là không quy định.
Đó là bước đầu tiên, bây giờ ECMAScript 5 Strict Mode không cho phép chúng hoàn toàn.
Nhưng tại sao?
Bởi vì họ được coi là một lỗi dễ bị tính năng, và trên thực tế, trong quá khứ họ gây ra không chủ ý hoặc khó để bắt lỗi - cũng giống như cùng một vấn đề của octals ngầm của parseInt
-.
Hiện tại, ở chế độ nghiêm ngặt, một chữ octal sẽ gây ra một ngoại lệ SyntaxError
- hiện chỉ có thể quan sát được trong Firefox 4.0 Betas -.
Đây là một câu trả lời tuyệt vời và nhiều hơn những gì tôi đã mong đợi ban đầu. Tôi đoán tôi bỏ qua 'StringNumericLiteral' trong spec, và tôi chắc chắn không biết rằng không gian trắng đã được cho phép. Đó chỉ là một trong những điều đó, tôi luôn mong đợi khoảng trắng sẽ dẫn đến * NaN *. –
Cảm ơn @Andy, vâng, tôi thực sự thường thấy mọi người ngạc nhiên rằng ví dụ: 'isNaN (" \ t \ r \ n ")' trả về 'false';) – CMS