Làm thế nào để làm parseInt()
và Number()
hành xử khác nhau khi chuyển đổi chuỗi thành số?
Làm thế nào để làm parseInt()
và Number()
hành xử khác nhau khi chuyển đổi chuỗi thành số?
Câu trả lời:
Chà, chúng khác nhau về mặt ngữ nghĩa , hàm Number
tạo được gọi là hàm thực hiện chuyển đổi kiểu và parseInt
thực hiện phân tích cú pháp , ví dụ:
// parsing:
parseInt("20px"); // 20
parseInt("10100", 2); // 20
parseInt("2e1"); // 2
// type conversion
Number("20px"); // NaN
Number("2e1"); // 20, exponential notation
Hãy nhớ rằng nếu parseInt
phát hiện số 0 đứng đầu trong chuỗi, nó sẽ phân tích số trong cơ sở bát phân, điều này đã thay đổi trên ECMAScript 5, phiên bản mới của tiêu chuẩn, nhưng sẽ mất nhiều thời gian để triển khai trình duyệt (nó không tương thích với ECMAScript 3), cũng parseInt
sẽ bỏ qua các ký tự dấu không tương ứng với bất kỳ chữ số nào của cơ sở hiện đang sử dụng.
Hàm Number
tạo không phát hiện các quãng tám:
Number("010"); // 10
parseInt("010"); // 8, implicit octal
parseInt("010", 10); // 10, decimal radix used
Nhưng nó có thể xử lý các số theo ký hiệu thập lục phân, giống như parseInt
:
Number("0xF"); // 15
parseInt("0xF"); //15
Ngoài ra, một cấu trúc được sử dụng rộng rãi để thực hiện chuyển đổi loại Số, là Toán tử Unary +
(trang 72) , nó tương đương với việc sử dụng hàm Number
tạo như một hàm:
+"2e1"; // 20
+"0xF"; // 15
+"010"; // 10
Number()
không giao dịch với các quãng tám giống như hex và nhị phân:Number('0o10') == 8
typeof parseInt("123") => number
typeof Number("123") => number
typeof new Number("123") => object (Number primitive wrapper object)
hai cái đầu tiên sẽ cung cấp cho bạn hiệu suất tốt hơn vì nó trả về một nguyên thủy thay vì một đối tượng.
new Number()
là khác nhau Number()
. typeof Number("123") => number
new Number("1") != new Number("1")
. KHÔNG BAO GIỜ SỬ DỤNGnew Number
. Không bao giờ không bao giờ không bao giờ. Number("1")
, mặt khác, là hoàn toàn hợp lý.
let x = new Number("2"); let y = new Number("2");
và sau đó thực hiện kiểm tra đẳng thức cho bất kỳ lý do nào, nên được gọi một if (x == y) { doSomething(); }
cách hợp lý doSomething
. Nhưng nó sẽ không. Ngoài ra nếu bạn chỉ phân tích một số let x = new Number("2");
thì x === 2
sẽ là sai. Đó là một lý do rõ ràng tại sao bạn không nên sử dụngnew Number
Nếu bạn đang tìm kiếm hiệu suất thì có lẽ kết quả tốt nhất bạn sẽ nhận được với sự thay đổi đúng theo từng bit "10">>0
. Cũng nhân ( "10" * 1
) hoặc không không ( ~~"10"
). Tất cả trong số họ là nhanh hơn nhiều của Number
và parseInt
. Họ thậm chí có "tính năng" trả về 0 cho đối số không. Dưới đây là các bài kiểm tra hiệu suất .
Number
và parseInt
vẫn chậm hơn 99% so với phần còn lại. Thêm vào đó, chúng cũng kém hấp dẫn về mặt thị giác :-)
parseInt
hoặc Number
là thích hợp hơn. Nếu bạn đang lập trình một trình giả lập N64 với hàng triệu chuyển đổi mỗi giây, bạn có thể xem xét các thủ thuật đó.
(2**31).toString() >> 0
sẽ tràn đến -2147483648
. Bạn có thể sử dụng >>>
thay vì >>
để JavaScript coi toán hạng là số nguyên 32 bit không dấu , nhưng sau đó bất kỳ số nào lớn hơn 2**32 - 1
cũng sẽ tràn.
Tôi tìm thấy hai liên kết hiệu suất so sánh giữa một số cách chuyển đổi string
sang int
.
parseInt(str,10)
parseFloat(str)
str << 0
+str
str*1
str-0
Number(str)
Một khác biệt nhỏ là những gì họ chuyển đổi undefined
hoặc null
,
Number() Or Number(null) // returns 0
trong khi
parseInt() Or parseInt(null) // returns NaN
parseInt()
:
NaN
sẽ được trả về.parseInt()
hàm gặp một giá trị không phải là số, nó sẽ cắt phần còn lại của chuỗi đầu vào và chỉ phân tích phần cho đến khi giá trị không phải là số.undefined
0, thì JS sẽ giả sử như sau:
ES5
xác định rằng 10 nên được sử dụng sau đó. Tuy nhiên, điều này không được tất cả các trình duyệt hỗ trợ, do đó luôn chỉ định cơ số nếu số của bạn có thể bắt đầu bằng 0.Number()
:
Number()
tạo có thể chuyển đổi bất kỳ đầu vào đối số thành một số. Nếu hàm Number()
tạo không thể chuyển đổi đầu vào thành một số, NaN
sẽ được trả về.Number()
tạo cũng có thể xử lý số thập lục phân, chúng phải bắt đầu bằng 0x
.console.log(parseInt('0xF', 16)); // 15
// z is no number, it will only evaluate 0xF, therefore 15 is logged
console.log(parseInt('0xFz123', 16));
// because the radix is 10, A is considered a letter not a number (like in Hexadecimal)
// Therefore, A will be cut off the string and 10 is logged
console.log(parseInt('10A', 10)); // 10
// first character isnot a number, therefore parseInt will return NaN
console.log(parseInt('a1213', 10));
console.log('\n');
// start with 0X, therefore Number will interpret it as a hexadecimal value
console.log(Number('0x11'));
// Cannot be converted to a number, NaN will be returned, notice that
// the number constructor will not cut off a non number part like parseInt does
console.log(Number('123A'));
// scientific notation is allowed
console.log(Number('152e-1')); // 15.21
Tôi luôn luôn sử dụng parseInt, nhưng hãy cẩn thận với các số 0 hàng đầu sẽ buộc nó vào chế độ bát phân .
parseInt(value, radix)
theo cách mà bạn không có chuyển đổi chế độ bát phân ngẫu nhiên , v.v.
0
, ngay cả trong chế độ không nghiêm ngặt. Nhưng điều này đã được sửa chữa và bây giờ các số 0 hàng đầu chỉ bị bỏ qua, vì vậy parseInt("070")
sẽ trở thành 70
.
parseInt()
.
parseInt()
-> Phân tích một số thành redix được chỉ định.
Number()
-> Chuyển đổi giá trị được chỉ định thành tương đương số hoặc NaN nếu không thực hiện được.
Do đó để chuyển đổi một số giá trị không phải là số thành số, chúng ta nên luôn luôn sử dụng hàm Number ().
ví dụ.
Number("")//0
parseInt("")//NaN
Number("123")//123
parseInt("123")//123
Number("123ac") //NaN,as it is a non numeric string
parsInt("123ac") //123,it parse decimal number outof string
Number(true)//1
parseInt(true) //NaN
Có nhiều trường hợp góc khác nhau cho các parseInt()
hàm vì nó thực hiện chuyển đổi, do đó chúng ta nên tránh sử dụng hàm parseInt () cho mục đích coersion.
Bây giờ, để kiểm tra thời tiết giá trị được cung cấp có phải là Số hay không, chúng ta nên sử dụng isNaN()
hàm riêng
parseInt chuyển đổi thành một số nguyên, nghĩa là, nó tước các số thập phân. Số không chuyển đổi thành số nguyên.
Đó là một ý tưởng tốt để tránh xa parseInt và sử dụng Number và Math.round trừ khi bạn cần hex hoặc bát phân. Cả hai đều có thể sử dụng chuỗi. Tại sao phải tránh xa nó?
parseInt(0.001, 10)
0
parseInt(-0.0000000001, 10)
-1
parseInt(0.0000000001, 10)
1
parseInt(4000000000000000000000, 10)
4
Nó hoàn toàn tàn sát số lượng thực sự lớn hoặc thực sự nhỏ. Thật kỳ lạ, nó hoạt động bình thường nếu các đầu vào này là một chuỗi.
parseInt("-0.0000000001", 10)
0
parseInt("0.0000000001", 10)
0
parseInt("4000000000000000000000", 10)
4e+21
Thay vì mạo hiểm để tìm lỗi với điều này và các vấn đề khác mà mọi người đã đề cập, tôi sẽ chỉ tránh parseInt trừ khi bạn cần phân tích một cái gì đó ngoài cơ sở 10. Number, Math.round, Math.foor và .toFixed (0) làm những điều tương tự parseInt có thể được sử dụng mà không có các loại lỗi này.
Nếu bạn thực sự muốn hoặc cần sử dụng parseInt cho một số phẩm chất khác của nó, đừng bao giờ sử dụng nó để chuyển đổi float thành ints.