Let’s talk about type conversion from a js interview question

1. Title

a Under what circumstances will the output statement be executed and print ok?

if (a == 1 && a == 2 && a == 3) {
    
    
  console.log('ok')
}

2. Solve

There are many solutions. Here we mainly discuss the problem of type conversion. More solutions are at the end of the article.

2.1, data type conversion

Divided into explicit conversion and implicit conversion.

Explicit conversion is also called forced conversion, and implicit conversion is also called automatic conversion.

Display conversion mainly refers to: manually converting different types of values ​​into numbers through Number(), String(), Boolean() , string or boolean.

Number()The parameters need to be discussed in two situations, one is the basic type and the other is the object.

Basic type value: The more special ones are these 3 types:

Number('324abc') // NaN
Number(undefined) // NaN
Number(null) // 0

The string is converted into a numerical value.Number()The rule is that as long as one character cannot be converted into a number, the entire string will be converted intoNaN. And parseInt() is analyzed one by one.

parseInt('123 cats') // 123
Number('321 cats') // NaN

Object: The conversion rules are as follows:

  1. Call the object's own valueOf method. If a primitive type value is returned, use Number() directly for the value and no further steps will be performed.

  2. If the valueOf method returns an object, the object's own toString method is called instead. If the toString method returns a value of a primitive type, use Number() for that value and do no further steps.

  3. IftoString the method returns an object, an error will be reported.

Let’s verify it:

const num = Number({
    
    
  valueOf() {
    
    
    return 2
  },
  toString() {
    
    
    return 3
  }
})
console.log(num) // 2
const num = Number({
    
    
  valueOf() {
    
    
    return {
    
    }
  },
  toString() {
    
    
    return 3
  }
})
console.log(num) // 3
const num = Number({
    
    
  valueOf() {
    
    
    return {
    
    }
  },
  toString() {
    
    
    return {
    
    }
  }
})
console.log(num) // TypeError: Cannot convert object to primitive value

so

Number({
    
    a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5

String()Number()Compared with , . toString() first instead of will call valueOf()


Boolean()The conversion rules are relatively simple. Except for the following 6, the others aretrue

Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
Boolean(false) // false

2.2, comparison operation

More detailed reference:How to compare correctly - MDN

Comparison operators are divided into two categories:Equality comparison andNon-Equality comparison . The rules for the two are different.

  • <, <=, >, >=, !=, !== Attribute inequality comparison sign.
  • == ===Belongs to the equality comparison operator.

Comparison method

For non-equality comparison, the algorithm is to first check whether the two operands are both strings. If so, compare them in dictionary order (Unicode code); otherwise, convert both operands to to compare the size. value

For equality comparison,

  • Strict equality operator=== compares whether the two values ​​are "the same value", and if the two values ​​are not of the same type, it returns false directly.
  • Equality operator== will convert them into the same type first, and then use strict equality operation Character comparison.
    • If the operands are both basic types, they are converted to numerical values ​​for comparison.
    • If one of the operands is an object and the other is a primitive value, the objects are converted to a basic type and compared (conversion The rules are consistent with using Number() to convert objects).

3. Solve

const a = {
    
    
  i: 1,
  valueOf() {
    
     // 这里用 toString 也可以。
    return this.i++;
  }
}

if(a == 1 && a == 2 && a == 3) {
    
    
  console.log('ok');
}

3. Other solutions

1. Use array’s toString()

a = [1,2,3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3);

Array.prototype.toString() - MDN

To put it simply, Array overwrites the object's toString(), and internally calls when calling toString() . So the method can be modified to achieve other purposes. join()join()

Similarly, arrays will also calltoString() to convert to basic types during comparison.

2,Object.defineProperty

let index = 0;
Object.defineProperty(window, 'a', {
    
    
  get: function() {
    
    
    return ++index;
  }
});
if (a == 1 && a == 2 && a == 3) {
    
    
  console.log('ok');
}

3. Hide spaces

Note that there are special spaces hidden on the left and right of a (String.fromCharCode(65440)). When the code is copied to vscode, it can be clearly seen that it is not an ordinary space.

var aᅠ = 1;
var a = 2;
var ᅠa = 3;
if(aᅠ==1 && a== 2 &&ᅠa==3) {
    
    
    console.log("ok")
}

that's all.

Guess you like

Origin blog.csdn.net/qq_40147756/article/details/134847997