Sự khác biệt giữa parseInt () và Number () là gì?


Câu trả lời:


456

Chà, chúng khác nhau về mặt ngữ nghĩa , hàm Numbertạo được gọi là hàm thực hiện chuyển đổi kiểuparseIntthự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 parseIntphá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 parseIntsẽ 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 Numbertạ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 Numbertạo như một hàm:

+"2e1";   // 20
+"0xF";   // 15
+"010";   // 10

Thật thú vị, liệu parseInt có bỏ qua bất kỳ ký tự nào theo sau số không? Bởi vì trong trường hợp của tôi, tôi thích nhận NaN thay vì 20 khi chuyển đổi.
Đánh dấu

Có nó làm. Âm thanh như bạn chắc chắn muốn Số ()
Gareth

Được rồi, vì vậy tôi đoán tôi sẽ đi với Number () nhưng cảm ơn rất nhiều vì đã làm rõ điểm này và tất cả những ví dụ này! :-)
Đánh dấu

1
Cảm ơn vì điều này. Đây là lần đầu tiên tôi thấy NaN. Nó có thể hữu ích cho một số người biết rằng NaN được kiểm tra với hàm isNaN (giá trị). Chỉ sử dụng "if (value == NaN)", chẳng hạn, sẽ không hoạt động.
WonderfulDay

1
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
Juan Mendes

22
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.


20
new Number()là khác nhau Number(). typeof Number("123") => number
Gareth

8
Ngoài ra 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ý.
Kragen Javier Sitaker

18
@Kragen, sẽ có ích hơn cho cộng đồng nếu bạn giải thích TẠI SAO bạn không nên sử dụng "Số mới" - thay vì chỉ gõ "không bao giờ" 5 lần ...
ken

1
@ken Nhận xét rất cũ nhưng đối với khách truy cập trong tương lai tôi tưởng tượng nó vì chính xác lý do họ đề cập để bắt đầu. Tôi phân tích hai số 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 === 2sẽ là sai. Đó là một lý do rõ ràng tại sao bạn không nên sử dụngnew Number
Tom C

1
@TomC Bạn đang thấy kết quả của một bình luận được chỉnh sửa (đó là biểu tượng bút chì sau bình luận biểu thị); trước đây không có lời giải thích, chỉ cần khuyên răn mạnh mẽ.
ken

15

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 NumberparseInt. 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 .


1
Tốc độ của các phương pháp khác nhau dường như thay đổi theo phiên bản trình duyệt theo thời gian. Thử nghiệm được liên kết cũng đã thay đổi và phiên bản mới nhất của nhận xét này có ở đây - jsperf.com/number-vs-parseint-vs-plus/39 - may mắn thay, trang web cũng chứa các phiên bản thử nghiệm trước đó
bobo

@bobo, chắc chắn rồi. Vì tò mò đã kiểm tra bằng chrome - NumberparseIntvẫ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 :-)
Saulius

15
Luôn thích sự rõ ràng của mã hơn tối ưu hóa "vô dụng". Đối với hầu hết các trường hợp sử dụng parseInthoặc Numberlà 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 đó.
ngryman

1
Câu hỏi là về hành vi, thảo luận về hiệu suất là ngoài chủ đề.
pneumatics

1
Lưu ý rằng điều này không thể được sử dụng cho các số nguyên lớn - cụ thể là các số nguyên không khớp với số nguyên 32 bit đã ký - bởi vì trong JavaScript, các toán tử bitwise coi toán hạng của chúng là một chuỗi 32 bit, thay vì thập phân, số thập lục phân, hoặc số bát phân. Do đó (2**31).toString() >> 0sẽ 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 - 1cũng sẽ tràn.
hasc


6

Một khác biệt nhỏ là những gì họ chuyển đổi undefinedhoặc null,

Number() Or Number(null) // returns 0

trong khi

parseInt() Or parseInt(null) // returns NaN

6

Tóm lược:

parseInt():

  • Lấy một chuỗi làm đối số thứ nhất, cơ số (Một số nguyên là cơ sở của hệ thống số, ví dụ thập phân 10 hoặc nhị phân 2) làm đối số thứ hai
  • Hàm trả về một số nguyên, nếu ký tự đầu tiên không thể được chuyển đổi thành một số NaN sẽ được trả về.
  • Nếu 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ố.
  • Nếu cơ số là undefined0, thì JS sẽ giả sử như sau:
    • Nếu chuỗi đầu vào bắt đầu bằng "0x" hoặc "0X", cơ số là 16 (thập lục phân), phần còn lại của chuỗi được phân tách thành một số.
    • Nếu giá trị đầu vào bắt đầu bằng 0, cơ số có thể là 8 (bát phân) hoặc 10 (thập phân). Cơ số nào được chọn là tùy thuộc vào việc triển khai công cụ JS. ES5xá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.
    • Nếu giá trị đầu vào bắt đầu bằng bất kỳ số nào, cơ số sẽ là 10

Number():

  • Hàm 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ố, NaNsẽ được trả về.
  • Hàm 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.

Thí dụ:

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


5

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 .


35
Tôi nghĩ rằng luôn luôn là một ý tưởng tốt để cung cấp một cơ số 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.
awesomo

Các số 0 đứng đầu sẽ buộc nó vào chế độ bát phân trong ECMAScript 3. ECMAScript 5 sẽ phân tích cú pháp 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.
Piotrek Hryciuk

2
Bạn cũng nên sử dụng một kẻ nói dối sẽ cảnh báo bạn cung cấp giá trị cơ số vào parseInt().
Justin

2

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


1

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.


1

Đó 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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.