Jane said
Recently I was a little dizzy by [] + {} and {} + []. I felt I understood it at that time, but I will forget it after a period of time. May not get the principle of the internal operation mechanism, or a half-understanding of the level. So, went to gnaw the basic knowledge of JS again, finally, I found the trick. Since then, JS data type conversion is no longer confused.
The text start
1. Data type of js:
Js data types include primitive types and reference types
Primitive types (7 types) : Number, String, Boolean, undefined, NULL, Symbol, BigInt
Reference type: Object
2. Explicit type conversion
- Number()
Conversion rules for converting a primitive type to Number:
Boolean: true to 1, false to 0 Symbol: Symbol type cannot be converted to NumberCopy the code
Rules for converting a reference type to Number:
If the method returns a valueOf the primitive type, then the conversion is performed according to the above rules. If the method returns a compound type, then the toString method of the object is called. If the toString method returns a valueOf the primitive type, then the toString method is called. Convert according to the above rules, if not, an error is reported
Through a few cases to deepen the impression:
Number({a:1})
// valueOf() -> {a:1} -> toString() -> '[object Object]' -> Number('[object Object]')-> NaN
Number([1.2])
/ / the valueOf () - > [1, 2] - > the toString () - > '1, 2' - > Number (' 1, 2) - > NaN
Number([1])
// valueOf() -> [1] -> toString() -> '1' -> Number('1') => 1
Number([])
// valueOf() -> [] -> toString() -> '' -> Number('') => 0
Number(function(){})
// valueOf() -> function(){} -> toString() -> 'function(){}' -> Number('function(){}') => NaN
Copy the code
- String()
Rules for converting a primitive type to String:
Numeric: Converts to a numeric string
String: string
Undefined: converts to ‘undefined’
Null: Converts to ‘null’
Boolean: Convert to ‘true’ or ‘false’
Symbol: Convert to ‘Symbol()’
Rules for converting a reference type to String:
If the result is a primitive type, the toString method is called. If the result returns a primitive type, the valueOf method is called. If the result returns a primitive type, the toString method is called. If the object type is returned, the conversion fails
Through a few cases to deepen the impression:
var a1 = { b : 1 };
a1.toString() // '[object Object]'
console.log(String(a1)) // '[object Object]'
var a2 = [1.2.3];
a2.toString() / / '1, 2, 3'
console.log(String(a2)) / / '1, 2, 3'
var a3 = function(){};
a3.toString() // 'function(){}'
console.log(String(a3)) // 'function(){}'
var a4 = [];
a4.toString() / /"
console.log(String(a4)) / /"
Copy the code
- Boolean()
Converting to Boolean is easier, just remember this:
Undefined: false
Null: false
NaN: false
“‘ : false
0: false
All but those listed above are converted to true
Implicit type conversion
Actions that trigger implicit type conversions: four operations, judgment statements, native calls (console.log and alert methods internally call String methods).
Except for addition (+), all the other operators (-, *, /, %) convert non-number types to Number types
+ : as an arithmetic operator, it converts other types to numeric types through Number(); The + is treated as a String concatenator when one of the two sides is a String, and the other types are converted to strings via String().
1 + 2 / / 3
// Both sides are Number types
1 +' ' / / '1'
// There are strings, other types are converted to strings
1+ false / / 1
// All other types are converted to Number and then added
1+ null / / 1
// All other types are converted to Number and then added
1+ undefined //NaN
// All other types are converted to Number and then added
1 + function(){} //'1function(){}'
// Reference types are converted to value types and then added according to the value types
1 + {} //'1[object Object]'
// Reference types are converted to value types and then added according to the value types
1 + [] / / '1'
/ / same as above
1+ [1.2] / / '11, 2'
/ / same as above
Copy the code
= = :
NaN is not equal to any value String converts to Number Boolean when comparing String with Number and Boolean converts to Number when comparing other types null and undefined equals when comparing reference types and value types, A reference type is first converted to a value type (internal call toPrimitive). A reference type is compared with a reference type to determine whether it refers to the same referenceCopy the code
Let’s take a look at some bad examples:
[] [] = =//false
// Reference type comparison, not pointing to the same reference is false[] = =0 // true
// [] converts to value type '',''== 0, Number('') -> 0, so true! [] = =0 // true
/ /! [] = false; Number(false) -> 0! [] [] = =//true
/ /! [] converts to value type '', false converts to Number(false) -> 0,'' converts to Number(") -> 0, so true{} = =! {}//false
/ /! {} is false, {} converts to value type '[object object]',false converts to Number(false) -> 0,'[object object]' converts to NaN, so false= = {} {}//false
// Reference type comparison, not pointing to the same reference is false
Copy the code
Classic interview questions
{} + {} //'[obiect Obiect][obiect Obiect]'
{} + [] / / 0
[] + {} //[obiect Obiect]
[] + [] / /"
Copy the code
for{} + {}
In Firefox, the result is NaN
5, have to mention the toPrimitive function
ToPrimitive (input,PreferredType): Converts an object to a value type
Symbol.toPrimitive is a built-in Symbol value that exists as a function value attribute of an object and is called when an object is converted to its original value.
ToPrimitive () converts a value of a reference type to an original value, which may be a String or a Number. The conversion rules for converting a reference type to String are the same as those for converting a reference type to Number.
Input is the object to be converted. When input is a raw value, return input directly
PreferredType is the desired type, which can be a string or a value.
unction ToPrimitive(input,PreferredType) {
var hint = PreferredType || 'default';
// If it is a raw value, return it directly
if( isPrimitiveType(input)){
return input
}
if(typeof input === 'symbol') {throw new Error('typeError')}if(input instanceof Date){
hint = 'string'
}
if (hint == "number" || hint == 'default') {
varres = input.valueOf(); ! isPrimitiveType(res) && (res = res.toString());if(isPrimitiveType(res)){
return res
}else{
throw new Error('typeError')}}if (hint == "string") {
varres = input.toString(); ! isPrimitiveType(res) && (res = res.valueOf());if(isPrimitiveType(res)){
return res
}else{
throw new Error('typeError')}}function isPrimitiveType(input){
var primitiveType = ['string'.'undefined'.'number'.'boolean'];
return (input === null || primitiveType.indexOf(typeofinput) ! = = -1); }}Copy the code