ES6 Learning II
Expansion of values
1. Binary, octal and hexadecimal notation
1.1 Representation of different bases
In js, 10进制
there is no need for any special representation, but 2进制
and 8进制
and 16进制
require special representation.
Before before, 16进制
the number represented by JS needs to start with 0x
(or 0X
)
0x00 === 0 // true
0x0A === 10 // true
0x0F === 15 // true
0x10 === 16 // true
8进制
The number represented needs to 0
start with
000 === 0 // true
007 === 7 // true
010 === 8 // true
2进制
The number represented needs to start with 0b
(or 0B
)
0b00 === 0 // true
0b01 === 1 // true
0b10 === 2 // true
However, 8进制
this 0
method of starting with the beginning is easy to cause ambiguity, and some browsers will parse it 10进制
as a string, so starting from ES5, in strict mode, octal is no longer allowed to use the prefix 0 to represent, and ES6 further clarifies that the prefix should be used 0o
(or 0O
) means
0o00 === 0 // true
0o07 === 7 // true
0o10 === 8 // true
1.2 Different base conversion
- Use
Number
the method to convert values in different bases to decimal values
Number(0x10) // 16
Number(0O10) // 8
Number(0b10) // 2
- Use
toString()
the method to convert it into a string of any base (the result is obtained without a prefix)
0b11111.toString(2) === '1111'
0b11111.toString(8) === '37'
// 默认转为10进制
0b11111.toString() === '31'
0b11111.toString(16) === '1f'
// 非常规进制也可以转换
0b11111.toString(6) === '51'
2. Methods of the Number object
2.1 Number.isFinite(), Number.isNaN()
ES6 provides two new methods, Number.isFinite() and Number.isNaN(), on the Number object. The difference between them and
the traditional global method is that the traditional method first calls to convert the non-numeric value into a numerical value, and then judges, and these two new methods are only valid for numerical values.isFinite()
isNaN()
Number()
Number.isFinite()
Used to check whether a value is finite (finite), that is, it is notInfinity
. At the same time, if the parameter type is not数值
,Number.isFinite
it will be returnedfalse
.
Number.isFinite(15); // true
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false
Number.isNaN()
Used to check whether a value isNaN
. At the same time, if the parameter type is notNaN
,Number.isNaN
it will be returnedfalse
.
Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false
Number.isNaN(9/NaN) // true
Number.isNaN('true' / 0) // true
Number.isNaN('true' / 'true') // true
2.2 and safe integers and Number.isInteger(), Number.isSafeInteger()
Since JavaScript adopts the IEEE 754 standard, values are stored in 64-bit double-precision format, and the numerical precision can reach up to 53 binary bits (1 hidden bit and 52 effective bits). That is, the range of integers that JavaScript can accurately represent is -2^53
between 2^53
and (excluding the two endpoints). If the precision of the value exceeds this limit, the 54th and subsequent bits will be discarded.
Math.pow(2, 53) // 9007199254740992
9007199254740992 // 9007199254740992
9007199254740993 // 9007199254740992 (精度丢失)
Math.pow(2, 53) === Math.pow(2, 53) + 1
// true
- ES6 introduced
Number.MAX_SAFE_INTEGER
andNumber.MIN_SAFE_INTEGER
these two constants are used to represent the upper and lower limits of this range.
Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1
// true
Number.MAX_SAFE_INTEGER === 9007199254740991
// true
Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER
// true
Number.MIN_SAFE_INTEGER === -9007199254740991
// true
Number.isSafeInteger()
It is used to judge whether an integer falls within the safe range.
Number.isSafeInteger('a') // false
Number.isSafeInteger(null) // false
Number.isSafeInteger(NaN) // false
Number.isSafeInteger(Infinity) // false
Number.isSafeInteger(-Infinity) // false
Number.isSafeInteger(3) // true
Number.isSafeInteger(1.2) // false
Number.isSafeInteger(9007199254740990) // true
Number.isSafeInteger(9007199254740992) // false
Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) // false
Number.isSafeInteger(Number.MIN_SAFE_INTEGER) // true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER) // true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1) // false
Be careful when using this function in practice. Verify that the result of the operation falls within the range of safe integers, not just the result of the operation, but each value involved in the operation.
In the calculation, if a certain value involved in the calculation exceeds the precision range, it will be stored in the form of in the computer, 9007199254740992
that is, to 9007199254740992
participate in the actual calculation.
Number.isSafeInteger(9007199254740993)
// false
Number.isSafeInteger(990)
// true
Number.isSafeInteger(9007199254740993 - 990)
// true
9007199254740993 - 990
// 返回结果 9007199254740002 = 9007199254740992-990
// 正确答案应该是 9007199254740003 = 9007199254740993 - 990
Number.isInteger()
Used to determine whether a value is an integer. Also, if the argument is数值
notNumber.isInteger
false
Number.isInteger(25) // true
Number.isInteger(25.0) // true
Number.isInteger(25.1) // false
// 参数不是数值
Number.isInteger() // false
Number.isInteger(null) // false
Number.isInteger('15') // false
Number.isInteger(true) // false
// 小数的精度达到了小数点后16个十进制位,转成二进制位超过了53个二进制位,导致最后的那个2被丢弃了
Number.isInteger(3.0000000000000002) // true
Number.isInteger(5E-324) // false
// 5E-325小于最小值5E-324,会被自动转为0,因此返回true
Number.isInteger(5E-325) // true
Notice
- Internally in JavaScript, integers and floats are stored the same way, so 25 and 25.0 are treated as the same value.
- Also affected by precision, values exceeding the safe range may be misjudged.
The Number object does not have a method for judging whether it is a floating-point number, because non-numeric values Number.isInteger
are also judged false
, so it is not possible to simply use inversion Number.isInteger
to judge whether it is a floating-point number
const a = 0.01
const b = '0.01'
Number.isInteger(a) // true
Number.isInteger(b) // true
// 联合Number.isFinite方法一起判断
Number.isFinite(a) && !Number.isInteger(a) // true
Number.isFinite(b) && !Number.isInteger(b) // false
2.3 Number.parseInt(), Number.parseFloat()
ES6 transplants the global methods parseInt() and parseFloat() to the Number object, and the behavior remains completely unchanged.
The purpose of doing this is to gradually reduce global methods and make the language gradually modular.
// ES5的写法
parseInt('12.34') // 12
parseFloat('123.45#') // 123.45
// ES6的写法
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45
3. Value separator
In European and American languages, longer values allow a separator (usually a comma) to be added every three digits to increase the readability of the value. For example, 1000 can be written as 1,000.
ES2021 , allows JavaScript values to use underscores ( _
) as delimiters. This numeric separator does not specify the number of intervals, that is, a separator can be added every three digits, or every digit, every two digits, or every four digits. And 整数
and 小数
, both 科学计数法
can be added
// 整数
123_00 === 12_300 // true
12345_00 === 123_4500 // true
12345_00 === 1_234_500 // true
// 小数
0.000_001
// 科学计数法
1e10_000
// 二进制
0b1010_0001_1000_0101
// 八进制
0o76_543_21_0
// 十六进制
0xA0_B0_C0
There are several points to note when using numeric separators.
- Cannot be placed at the front (leading) or last (trailing) of the value.
- Two or more delimiters cannot be concatenated.
- There cannot be separators before and after the decimal point.
- In scientific notation, there cannot be separators before and after the e or E that represents the exponent.
- The delimiter cannot immediately follow the prefix of the base
0b
,0B
,0o
,0O
,0x
,0X
The value separator is just a writing convenience, and has no effect on the storage and output of JavaScript's internal values. At the same time, the numeric separator is only supported by numeric types. If it is replaced with a string, it will be treated as a normal string. The main reason is that the language designer believes that the value separator is mainly for the convenience of writing values when coding, rather than for processing externally input data.
Number('123_456') // NaN
Number(123_456) // 123456
parseInt('123_456.01') // 123
parseInt(123_456.01) // 123456
parseFloat('0.000_100') // 0
parseFloat(0.000_100) // 0.0001