Let me talk about the conclusion:
parseInt is more reliable, but pay attention to the type and number of parameters;
There will be some problems with using bitwise operators (
<<0) to "round", and it is not recommended in general;
After all, bit operations are operators, and the efficiency is higher. If this "rounding" operation is a key operation that affects performance, and you know that the operand will not exceed the precision limit, you can consider using bit operations
Number.parseInt accepts two parameters by default
The first parameter is a string type value by default. If it is not, it will be forced into a string type value through the abstract ToString. There will be various pits in the forced type conversion process.
The second parameter is the base of the number type. If it is not, it will be coerced into a value of the number type through the abstract ToNumber. The range is 2-36. After the coercion type conversion, if it is other value, it will return NaN. Before ES5, if this parameter is not passed in, the base will be judged based on the beginning of the first parameter, and the string starting with 0 will be judged as an octal base, which is the old yellow calendar pit mentioned by @user. It has been resolved after ES5. If this parameter is not passed, it will default to decimal. But this parameter is easy to be ignored, especially when it is used with a function like map that also easily ignores subsequent optional parameters, such as
['10', '10', '10', '10'].map(parseInt) // The result is [10, NaN, 2, 3]
So if you just use parseInt to "round up", a good habit is to always remember to set the second parameter to 10
Then try not to use parseInt to convert some other types of values. If you really encounter a result that needs to be judged (such as some idle interviewers have to investigate this), then first evaluate the two parameters and convert Into the corresponding type, and then judge.
The judgment process can be roughly understood as: the conversion result of the first parameter removes the blanks, and then extracts from left to right the integer part that can be understood in the base specified by the second parameter, and returns the value of this value in decimal base. If conversion fails, return NaN
Before looking at the bit operation, we must first make it clear (personal understanding, not necessarily accurate):
One thing to note is that bitwise operations will treat NaN and Infinity as 0.
The operands participating in bit arithmetic will first perform the abstract ToInt32 operation on it, the most important in Specification The third and fourth steps are:
- Let posInt be sign(number) * floor(abs(number)).
- Let int32bit be posInt modulo 2^32; that is, a finite integer value k of Number type with positive sign and less than 2^32 in magnitude such that the mathematical difference of posInt and> k is mathematically an integer multiple of 2^32.
Simply put, rounding and remainder, there will be two problems here:
The method of rounding is different from Math.floor. ToInt32 rounds the absolute value and then adds a sign, and Math.floor rounds directly down. For example,
ToInt32(-1.5) == -1, and
Math.floor(-1.5) == -2
The method of seeking surplus is a bit complicated. In short, unexpected things will happen under certain conditions (leave a hole first, and I will interpret it carefully when you have time)
<<0 here do not perform specific displacement operations on the actual value, but the ToInt32 operation will still be performed. Within a certain range, it is simply rounded by the absolute value, beyond this The range will become an unexpected value
~ Is also a bitwise operator. Like the shift operator above, it also passes ToInt32 first. Its function is to flip the binary form of the operand bit by bit. So two ~~ connected together is equivalent to the following operations:
Perform ToInt32 on the operand
Flip by bit again
In fact, it still uses the absolute value of ToInt32 to round up
In addition, there is a trick about the ~ operator that is more practical:
The value of ~(-1) is 0, and -1 is the only value that returns a false value after the ~ operation (including other special values such as
, etc. will not return False value)
The indexOf function of string and array will return -1 if it fails to find it, then you can use it
if(~str.indexOf('str')) // to indicate found
It is more elegant than judging >= 0 or != -1, and it is similar to using
!! to judge non-false values.