preface

This article is part of a series of articles on the basics of JavaScript. It focuses on type conversion, equality judgment, and operator precedence in JavaScript. At the end of the article, I prepared some common type conversion interview questions. Daily blog is recorded in wordfinch, welcome to follow my wordfinch documentation.

If the article is helpful to you, please click on the like comment favorites and forward. If you have any questions or doubts, please leave a message in the comment section, and I will reply to you as soon as possible. If you think there is any knowledge point wrong in my article, PLEASE kindly inform me. It is fatal to understand the wrong things in pairs, no matter what industry you are in.

Type conversion

Implicit conversion of types exists in equality judgment. We need to first understand the basic rules of data type conversion. Here we mainly discuss basic data types, common objects, and some special values or types.

Note: global propertiesNaN The value of represents not a number, usedisNaNJudge.

ToString

The constructor string () and toString can be used to convert toString. The difference is that toString raises an exception for null and undefined.

console.log(String(000111)) / / 73
console.log(000111.toString()) / / 73

/ / Number. The prototype. ToString (radix) offer a parameter, specify the base, the default value is 10.
console.log(000111.toString(3)) / / 2201
Copy the code
console.log(String(1),typeof String(1))// 1 string
console.log(String(-100),typeof String(-100))// -100 string
console.log(String(1.23),typeof String(1.23))/ / 1.23 string
console.log(String(1e221),typeof String(1e221))// 1e+221 string

console.log(String(3333n),typeof String(3333n)) // 3333 string

console.log(String(Infinity),typeof String(Infinity))// Infinity string

console.log(String(NaN),typeof String(NaN))// NaN string

console.log(String(false),typeof String(false))// false string
console.log(String(true),typeof String(true))// true string

console.log(String(null),typeof String(null))// null string
console.log(String(undefined),typeof String(undefined))// undefined string

console.log(String([]),typeof String([]))// string
console.log(String([1]),typeof String([1]))// 1 string
console.log(String([1.'2'.false.null.undefined.NaN.Infinity]),typeof String([1.'2'.false.null.undefined.NaN.Infinity]))/ / 1, 2, false,,, NaN, Infinity string

console.log(String({}),typeof String({})) // [object Object] string
console.log(String({a:1}),typeof String({a:1})) // [object Object] string

console.log(String(Symbol("foo")),typeof String(Symbol("foo"))) // Symbol(foo) string
Copy the code

summary

  1. Null, and undefinedAnd Boolean value, NaN, SymbolConvert to their respective strings;
  2. A string that converts numeric types directly to numeric types (includingInfinity, a negative string) is exponentially expressed aseAnd then add one+Number, and other base values to decimal;
  3. BigIntThe type is left outnA string of symbols;
  4. An empty array is converted to an empty string. A non-empty array is converted to a string using a joinnullandundefined, treated as an empty string;
  5. Object converted to string is"[object Object]"

ToNumber

You can convert to number using the constructor number or parseFloat or parseInt, which are not related to implicit conversions and are not covered in this article.

console.log(Number('12321'), typeof Number('12321'))// 12321 number
console.log(Number('mobile phone 1'), typeof Number('mobile phone 1'))// NaN number
console.log(Number('1.23 mobile phones'), typeof Number('1.23 mobile phones'))// NaN number
console.log(Number(' '), typeof Number(' '))// 0 number

console.log(Number(3333n), typeof Number(3333n)) // 3333 number

console.log(Number(Infinity), typeof Number(Infinity))// Infinity number

console.log(Number(NaN), typeof Number(NaN))// NaN number

console.log(Number(false), typeof Number(false))// 0 number
console.log(Number(true), typeof Number(true))// 1 number

console.log(Number(null), typeof Number(null))// 0 number
console.log(Number(undefined), typeof Number(undefined))// NaN number

console.log(Number([]), typeof Number([]))// 0 number
console.log(Number([1]), typeof Number([1]))// 1 number
console.log(Number([1.1]), typeof Number([1.1]))/ / 1.1 number
console.log(Number([1.11.2]), typeof Number([1.11.2]))// NaN number
console.log(Number(['1.11'.2]), typeof Number(['1.11'.2]))//NaN number
console.log(Number([1.'2'.false.null.undefined.NaN.Infinity]), typeof Number([1.'2'.false.null.undefined.NaN.Infinity]))// NaN number

console.log(Number({}), typeof Number({})) // NaN number
console.log(Number({a: 1}), typeof Number({a: 1})) // NaN number

console.log(Number(Symbol("foo")), typeof Number(Symbol("foo"))) // Cannot convert a Symbol value to a number
console.log(Number(333n), typeof Number(333n))// 333 number
Copy the code

summary

  1. nullAnd empty character, empty array conversion0.undefinedtoNaN.NaNandInfinityThe same;
  2. A purely numeric string is converted to the corresponding number, and everything else is convertedNaN;
  3. trueandfalseto1and0;
  4. Array objects may need to be performedToPrimitiveTransformation, see later;
  5. The first part of the array is a value, converted to that value, otherwise converted toNaN;
  6. Object toNaN;
  7. BigIntIs an array with the n Symbol removed. Symbol cannot be converted.

ToBoolean

To convert to Boolean, you can use the constructor Boolean;

console.log(Boolean(1),typeof Boolean(1))// true boolean
console.log(Boolean(-100),typeof Boolean(-100))// true boolean
console.log(Boolean(1.23),typeof Boolean(1.23))// true boolean
console.log(Boolean(1e221),typeof Boolean(1e221))// true boolean

console.log(Boolean(3333n),typeof Boolean(3333n)) // true boolean

console.log(Boolean(Infinity),typeof Boolean(Infinity))// true boolean

console.log(Boolean(NaN),typeof Boolean(NaN))// false boolean

console.log(Boolean(false),typeof Boolean(false))// false boolean
console.log(Boolean(true),typeof Boolean(true))// true boolean

console.log(Boolean(null),typeof Boolean(null))// false boolean
console.log(Boolean(undefined),typeof Boolean(undefined))// false boolean

console.log(Boolean([]),typeof Boolean([]))//true boolean
console.log(Boolean([1]),typeof Boolean([1]))// true boolean
console.log(Boolean([1.'2'.false.null.undefined.NaN.Infinity]),typeof Boolean([1.'2'.false.null.undefined.NaN.Infinity]))// true boolean

console.log(Boolean({}),typeof Boolean({})) // true boolean
console.log(Boolean({a:1}),typeof Boolean({a:1})) //true boolean

console.log(Boolean(Symbol("foo")),typeof Boolean(Symbol("foo"))) // true boolean

Copy the code

All but these are true

console.log(Boolean(false),typeof Boolean(false))// false boolean
console.log(Boolean(0),typeof Boolean(0))// false boolean
console.log(Boolean(-0),typeof Boolean(-0))// false boolean
console.log(Boolean(0n),typeof Boolean(0n))// false boolean
console.log(Boolean(NaN),typeof Boolean(NaN))// false boolean
console.log(Boolean(null),typeof Boolean(null))// false boolean
console.log(Boolean(undefined),typeof Boolean(undefined))// false boolean

// These three are reduced to empty strings
console.log(Boolean(""),typeof Boolean(""))// false boolean
console.log(Boolean(' '),typeof Boolean(' '))// false boolean
console.log(Boolean(` `),typeof Boolean(` `))// false boolean
Copy the code

summary

There is a term in JavaScript called falsy. Falsy contains eight values that are false and all other values that are true when converted to Booleans.

ToPrimitive

ToPrimitive is interpreted in MDN as converting arguments ToPrimitive types by attempting to call the valueOf() and toString() methods of the object.

If valueOf returns a valueOf the original type, ToPrimitive returns that value. If valueOf does not exist, or if valueOf does not return a valueOf the original type, It tries to call the object’s toString method, that is, it follows the object’s toString rules, and then uses the return value of toString as the result of ToPrimitive. Note: ToPrimitive has different rules for different types of objects, such as Date objects that call toString first. For details, see the ECMA standard

ValueOf and toString

let exp=new String(1) // Construct a number 1 using String
console.log(typeof a) // The type is 'object'
console.log(exp.valueOf()) / / "1"
console.log(typeOf exp.valueOf()) // the primitive type of 'string' is "1", which is of type 'string'
Copy the code
console.log(Number([])) / / "= > 0
console.log(Number(['10'])) / / '10' = > 10

const obj1 = {
    valueOf() {
        return 1
    },
    toString() {
        return 2}}console.log(Number(obj1))  / / 1

const obj2 = {
    toString() {
        return 2}}console.log(Number(obj2)) / / 2

const obj3 = {
    toString() {
        return{}}}// if neither valueOf nor toString returns a valueOf the original type, an exception is thrown.
console.log(Number(obj3)) //TypeError: Cannot convert object to primitive value

Copy the code

summary

ToPrimitive conversions are done when an object type needs to be converted to a primitive type. Let’s take a few examples.

  1. String({})Empty objects are called firstvalueOf, but returns the object itself{}Is not a primitive type, so the call continuestoString,'[object Object]'.String('[object Object]'), so the result after transformation is'[object Object]';
  2. Number([])Empty arrays are called firstvalueOf, but returns the array itself[]Is not a primitive type, so the call continuestoString,' ', which is equivalent toNumber(''), so the result after transformation is0;
  3. Look at the abovevalueOfandtoStringExample,obj1.valueOf()The basic type is returned1, so it will not be executedtoString.ToPrimitiveIs equal to 1Number(1);
  4. obj2There is novalueOfMethod, will executetoString.toStringReturn to 2,ToPrimitiveAs the result of the2, which is equivalent toNumber(2);
  5. obj3thetoStringMethod does not return a primitive typeToPrimitive, so an error is thrown;
  6. Pay attention toBoolean()The transformation,falsyAll values other thantrue;

Now that we’ve summarized some of the rules for casting, let’s look at equality judgment in JavaScript.

Equality judgment

Four kinds of algorithms

  1. Comparison of non-strict (abstract) equality:= =
  2. Strict equality comparison:= = =
  3. Zero equals:0 = = = 0
  4. Be equal to:Object.is()

Nonstrict equality

MDNWe need to remember him undefinedandnull Comparison istrue

console.log(undefined= =null) //true
console.log(null= =null) //true
console.log(undefined= =null) //true
Copy the code

The other types are false for shallow comparisons with undefined and null

console.log(1= =null) //false
console.log("null"= =null) //false
console.log(false= =null) //false
console.log(NaN= =undefined) //false
console.log(true= =undefined) //false
console.log(Infinity= =undefined) //false
console.log({}==undefined) //false
console.log([]==undefined) //false
Copy the code

8 falsy values are assumed to be false, and the other values are converted to Boolean values to be true;

console.log(!!false) //false
console.log(!!0)     //false
console.log(!! -0)    //false
console.log(!!0n)    //false
console.log(!!' ')    //false
console.log(!!"")    //false
console.log(!!null)  //false
console.log(!!undefined)//false
console.log(!!NaN)   //false
Copy the code

Special case, narrow object document.all equals null and undefined

console.log(null= =document.all) //true
console.log(undefined= =document.all) //true
Copy the code

Number, String, Boolean, Object, Array comparison (follow the table above or the following figure) :

  1. The same type is congruent comparison;
  2. All other comparisons are converted into numerical comparisons;

summary

  1. undefinedandnull Comparison istrue;
  2. Other types andundefined,nullComparison isfalse;
  3. eightfalsyValue asfalseAll other values are converted to Booleanstrue;
  4. Special case, narrow objectdocument.allIs equal to thenullandundefined
  5. Number, String, Boolean, Object, ArrayComparison:
    • The same type is congruent comparison;
    • All other comparisons are converted into numerical comparisons;

Strictly equal

There are two special judgments of strict equality:

  1. + 0Is equal to the0(to distinguish+ 00It is necessary to solve certain mathematical problems);
  2. NaNIs not equal toNaN.
console.log(undefined= = =undefined) //true
console.log(null= = =null)//true
console.log(null= = =undefined) //false

console.log(+0= = = -0)   //true
console.log(0= = =0)     //true
console.log(NaN= = =NaN) //false
Copy the code

Zero is equal to && is equal to

The different judgments of 0 and NaN in strict equality must be confusing. In JavaScript, Object. Is is used to judge equal value equality, mainly to solve the problem of positive and negative zero and NaN in strict equality.

console.log(Object.is(+0, -0)) //false
console.log(Object.is(NaN.NaN)) //true
Copy the code

Operator priority

Some rules to summarize:

  1. Type conversions are specified by operators;
  2. ToPrimitiveGenerally acting on= =Such as! []You don’t have to do itToPrimitiveConversion, equivalent to! Boolean([]);
  3. The rear+Used as a character concatenation, other types are mostly converted to numeric types;
  4. As long as one of them is a string, the other one is converted to a string;
  5. Value addednullorundefinedSo let’snullorundefinedforNumber()Conversion.

Part of the operator priority: to mock the markdown table, here can only be images, do not want to paste a lot of HTML, the table is here [suggested by the actor] 13 implicit conversion interview questions, let you enjoy the end

Will do topics

Do not want to do 😣😣😣😣

Title 1

Define a variable a such that the expression a == 1&&a == 2&&a == 3 results in true.

// We can use valueOf, which increases the value by 1 each time we read it
//let num=0
const a = {
  num: 0.valueOf: function() {
    //return num += 1
    return this.num += 1}};const equality = (a==1 && a==2 && a==3);
console.log(equality); // true
Copy the code

This can also be done using Object.defineProperty.

let val=1
Object.defineProperty(window.'a', {
    get: function() {
        return val++
    }
});

console.log(a == 1 && a == 2 && a == 3)

Copy the code

Topic 2

Why the expression [] == 0 results in true. Answer:

  1. Array firstToPrimitiveThe transformation,[].valueOf().toString(), the value is an empty string;
  2. For now' '= = 0A null character is converted to a number0;
  3. 0and0Compared totrueThe judgment is true.

Topic 3

Why does the expression [] ==! [] results in true. Answer:

  1. Operator precedence and implicit type conversions are considered here.!Priority than= =High, right! []You don’t have to do itToPrimitiveConversion, direct! Boolean([])The results forfalse;
  2. Now it is[] == falseAt this point, the left side is going to do itToPrimitiveYes, and according to the rules of conversion,[].valueOf().toString()Is an empty string' '
  3. Now it is''==false, both sides are converted to numerical calculation;
  4. Empty string to number is0The right side,falseThe same goes for numbers0.0and0Equal, it’s true.

Topic 4

Answer:

// string '0' converts to value 0, false converts to value 0
'0'= =false // true

// The array has only one value and is either a number or a string.
String '0' is converted to a value of 0. False is converted to a value of 0
['0'] = =false // true

// The array has only one value and is either a number or a string.
String '2' is converted to 2, 2==2
[2] = =2  //true 

// Empty array is converted to string ""," "empty to value 0, false to value 0[] = =false // true 

// Array null and undefined are treated as empty strings when converted to strings.
//[null].valueof ().toString() is an empty string
[null] = =0 // true

///[null].valueof ().toString() is an empty string.
[null] = =false // true

// Array null and undefined are treated as empty strings when converted to strings.
//[undefined].valueof ().toString() = 0; //[undefined].valueof ().
[undefined] = =false // true

// All other types are false for shallow comparisons with undefined and null
undefined= =false // false
null= =0 // false
null= =false // false

Copy the code

Topic 5

Find the value of true + false. Answer: Convert to adding numbers, 1+0=1

Topic 6

“Number” + 15 + 3 The ‘+’ operator executes from left to right, so “number” + 15 is executed first, converting 15 to string to get “number” and then “number15” + 3 to get “number153”.

Topic 7

100 + true + 21.2 + null + undefined + “Tencent” + [] + null + 9 + false Solution: There is no operator priority here, so it starts from the left side. Ok, let’s start the decomposition

  1. 100 + true, add values and Boolean values, convert Boolean values into numbers, and get100 + 1 = 101;
  2. 101 + 21.2,Add the values to the values, and you get101 + 21.2 = 122.2;
  3. 122.2 + nullNumerical and,nullTogether,nullto0.122.2 + 0 = 122.2;
  4. 122.2 + undefinedNumerical and,undefinedTogether,undefinedIt turns into a numberNaN.NaNAnd the sum of the values isNaN, 122.2 +NaN=NaN;
  5. NaN+ "Tencent".NaNThe conversion to string is'NaN',"NaN"+ "Tencent"="NaNTencent";
  6. "NaNTencent" + [], an empty array into a string is""."NaNTencent" + ""="NaNTencent";
  7. "NaNTencent" + null.nullTo a string"null"."NaNTencent" + "null"="NaNTencentnull";
  8. "NaNTencentnull" + 9, string and numbers add, plus has the function of concatenation, the9To a string"9"."NaNTencentnull" + "9"="NaNTencentnull9";
  9. "NaNTencentnull9" + false, string and Boolean values, addfalseTo a string"false"."NaNTencentnull9" + "false"="NaNTencentnull9false";
let result = 100 + true + 21.2 + null + undefined + "Tencent"+ + []null + 9 + false;
console.log(result) //'NaNTencentnull9false'
Copy the code

The title 8

{} + [] + {} + [1]

  1. On the left side of the{}Is treated as an empty block of execution, not as an object, which has no return value+[] + {} +[1];
  2. +Is a unary operator that takes precedence over the unary operator[]It turns into a number0And is now0 + {} + [1];
  3. Object to string is"[object Object]";0+"[object Object]"+[1]get"0[object Object]"+[1];
  4. [1]To a string"1", the results for"0[object Object]1".
let result = 100 + true + 21.2 + null + undefined + "Tencent"+ + []null + 9 + false;
console.log(result) //'NaNTencentnull9false'
Copy the code

Topic 9

O! + [] + [] +! [] :

  1. Precedence is sorted first, and logic is executed from right to left when added together with unary! (+ []) + [] + ![];
  2. +Is treated as a unary operator, (+ [])So this is equal to0;
  3. For now! [] 0 + +! []= >! 0right0To perform Boolean substitution,0isfalseforfalseTake the fortrue;
  4. true+ [] + ! [] [] ` `Convert to a BooleantrueCovariates,false;
  5. []To a string' ';
  6. true+ '' + falseIf you put all three together, you get"truefalse".

The title 10

The comparison operator > performs an implicit conversion of type [1] to a number equal to 1, null equal to 0, 1>0 equal to true.

Topic 11

Answer: Convert to “foo” + (+”bar”); The right-hand side has a higher priority, and (+”bar”) triggers an implicit conversion of type number to a number of NaN, with “foo” +NaN concatenated to ‘fooNaN’.

The subject of 12

O 0 | | “0” && {} answer: logical operators for Boolean type conversion, converted to Boolean value 0 is false, 0 | | “0” on the right set up a “0” && {}, string “0” is a Boolean value of true, return to the right, get {}.

Topic 13

[1,2,3] == [1,2,3]; [2,3] == [1,2,3];

conclusion

Read so long, hard, but I also wrote for a long time ah, might as well click a “like” and then go. 😁😁😁 can also check out my other two articles in this series, hey hey hey

🎉🎉 On New Year’s Day 2022, I finally figured out the prototype and prototype 🎉🎉 port 2022 cc JavaScript hyperdetailed loop summary

reference

The equality judgment in JavaScript starts with an interview question — JS implicit conversion step pit set Falsy virtual value