Table of contents
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:
-
Call the object's own
valueOf
method. If a primitive type value is returned, useNumber()
directly for the value and no further steps will be performed. -
If the
valueOf
method returns an object, the object's owntoString
method is called instead. If thetoString
method returns a value of a primitive type, useNumber()
for that value and do no further steps. -
If
toString
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.