Implicit conversion in Js is often a pain point in front-end development. In daily development, we probably know the concept of implicit conversion for different data types in different operations. So, what are the rules for implicit transformations, and what are the scenarios for implicit transformations down to the nitty-gritty? With doubt, I went through MDN and sorted out some basic things.
- Primitive type conversion ([string, number, Bigint, Boolean, NULL, undefined, symbol]), usually using the conversion function string, number, Boolean
- When an object is converted to its original value, the function ToPrimitive is called, depending on the operator and context
- When the conversion type is expected to be Number or the default value, try converting valueOf to toString in turn
- When the expected value is String, try toString and valueOf in turn
- The presence of the [Symbol. ToPrimitive] method interferes with the intended conversion
- The original symbol value cannot be converted to a string or number, so it must be converted to its wrapper object and then converted to a string by calling the toString() method
Symbol(1) + 1 // TypeError: Cannot convert a Symbol value to a number
Symbol(1) + 'hello' // TypeError: Cannot convert a Symbol value to a string
Symbol(1).toString() + 1 // "Symbol(1)1"
Copy the code
Symbol.toPrimitive
The built-in Symbol value, which exists as a function value attribute of an object and is called when an object is converted to the corresponding original values (expected to be String, number, and default). Parameter hint, indicating the expected type of the original value to be converted to
const object1 = {
[Symbol.toPrimitive](hint) {
console.log(hint) // number, default, string
if (hint == 'number') {
return 42;
}
return null; }};console.log(+object1);
console.log(object1);
console.log(1 + object1);
console.log(String(object1));
console.log(! object1)// No hint value is printed
Copy the code
The impact of single operators on implicit conversions
Unary operation (+/-)
- Expected transfer number
+undefined //NaN
+null / / 0
+'1' // -1+ []/ / 0+ {}//NaN
+false / / 0
+true / / 1
+Symbol(1).toString() // NaN
+(() = > {}) // NaN
+Date(a)// NaN
+new Date(a)/ / 1586502202192
+Infinity // Infinity
+NaN // NaN
Copy the code
Bitwise not (~)
- Expected transfer number
- The bitwise non-operation on any number x results in -(x + 1)
~undefined / / 1
~null // -1
~'1' / / 0~ []// -1~ {}// -1
~false // -1
~true / / - 2
~Symbol(1).toString() // -1
~(() = > {}) // -1
~Date(a)// -1
~new Date(a)/ / - 1662234207
~Infinity // -1~ -Infinity // -1
~NaN // -1
~0 // -1
Copy the code
Logic (!)
- Expect to turn a Boolean
!undefined // true
!null // true
!'1' // false
!' ' // true! []// false! {}// false
!false // true
!true // false
!Symbol().toString() // false
!Symbol(a)// false
!(() = > {}) // false
!Date(a)// false
!new Date(a)// false
!Infinity // false
!NaN // true
Copy the code
Increasing (+ +) | decreasing (-)
- Expected transfer number
let a = [], b = {}, c = (a)= > {}, d = null, e = false, f = '1'
a++ / / 1
b++ // NaN
c++ // NaN
d++ / / 1
e++ / / 1
f++ / / 2
Copy the code
Implicit conversions in expressions
Plus (+)
The addition operator is used to sum values or concatenate strings.
- String concatenation is expressed when there is a string in the context
0 + '1' / / '01'
'0' + null // '0null'
'0' + undefined // '0undefined'
'0' + true // '0true'
'0' + Symbol(1) // Uncaught TypeError: Cannot convert a Symbol value to a string
Copy the code
- When there is no string context, the original data type is expected to be converted to Number, the non-original data type is expected to be converted to String, and the hint parameter of toPrimitive is default
0 + null / / 0
0 + undefined // NaN
1 + Infinity // Infinity
1 + false / / 1
0 + true / / 1
1 + Symbol(1) // Uncaught TypeError: Cannot convert a Symbol value to a number
1 + null / / 1
undefined + null // NaN
false + null / / 0
true + null / / 1
1 + (() = > {}) / / "(1) = > {}"
1 + function a() {} // "1function a() {}"
0 + {} // "0[object Object]"
{} + undefined // "[object Object]undefined"
null + {} // "null[object Object]"
{} + (() = > {}) //"[object Object]() => {}"
{} + [] // "[object Object]"
[] + undefined // 'undefined'
[] + null // 'null'
[1] + 2 / / '12'
[] + (() = > {}) / / "() = > {}"
Copy the code
Subtract (-) | multiply (*) | in addition to (/) yu (%) | o | power (* *)
- Expected transfer number
0 - null / / 0
0 / undefined // NaN
1 % Infinity / / 1
true ** false / / 1
undefined * null // NaN
1 - (() = > {}) // NaN
0 * {} // NaN
{} / (() = > {}) // NaN
{} % [] // NaN
[2] * *2 / / 4
[1.2] - {} // NaN
Copy the code
Bitwise and (&) | bitwise or (|) | the bitwise xor (^) | left moves to the right (< <) | symbols (> >) | unsigned right shift (> > >)
- Bitwise operands after expected conversion to number
The Bitwise operators treat their operands as a sequence of 32-bit bits (0 and 1). All the operands of the Bitwise operators are converted to signed 32-bit integers of the form two’s complement.
14 & {}
// NaN = 00000000000000000000000000000000
/ / 14 = 00000000000000000000000000001110
// 14 & 9 = 00000000000000000000000000000000 = 0
14 | - 1
/ / - 1 = 11111111111111111111111111111111
// 14 | -1 = 11111111111111111111111111111111 = -1
14 ^ true
/ / 1 = 00000000000000000000000000000001
// 14 ^ 1 = 00000000000000000000000000001111 = 15
14 << 4
/ / 14 < < 4 = 00000000000000000000000011100000 / / 2 * * * * 6 + 2 * 7 + 2 * 5 = 224
14 >> Date(a)// 14 >> NaN = 00000000000000000000000000001110 // 14
// 14 >> new Date() = 0 // 0
14> > > [2]
/ / 14 > > = 00000000000000000000000000000011/2/3
Copy the code
Equal (==) and unequal (! =)
- The two operands are converted to the same type and compared
- For relational operators (such as <=), the operands are converted to their original values so that they are of the same type and then compared.
- A non-primitive type of the same type that compares addresses in memory
false= = []// true
'[object Object]'= = {}// true
(function a() {}) > = ({})// true
[1] = =1 // true
NaN= =NaN // false
{} != NaN // false[] [] = =// false, memory address is different= = {} {}// false, memory address is different! [] [] = =// true, hint is number -> false == 0 -> 0 == 0! = = {} {}// false, false == NaN -> 0 == NaN
Copy the code
What do you know about implicit conversions? Implicit conversions don’t know how many more!