How to make a == 1 && a == 2 && a == 3 return true?

A == 1; a == 2; a == 3; a == 1; a == 2; – Implicit conversions will be performed (see JS Personal Learning (2) – Operator related)

In brief, here are some of the implicit conversions we encounter with the equality operator (==) :

  • Both values are of the same type:
  1. String, Boolean: indicates whether two values are the same. The value is true if they are the same, and the value is false if they are different
  2. Undefined, Null: returns true
  3. Return false for NaN, true for -0 and +0, false for -infinity and Infinity
  4. Let a = {}; let a = {}; let b = a; console.log(a == b); // true
  • The two values are of different types:
  1. Null and undefined return true
  2. The Number is compared with String, and String turns to Number
  3. If you have type Boolean, first convert Boolean to Number
  4. For type Object, get it firstThe original valueAnd then compare
  5. Undefined == 0 returnsfalse, null == 0 returnsfalse

For more details, please refer to the following figure:

As we can see from the figure, a variable a cannot be equal to 1, 2, 3, or ‘1’, ‘2’, and ‘3’ at the same time, and it can only be converted to 0 or 1 if a is of type Boolean, so start only if a is of type Object.

The implicit conversion rules for the equality operator (==) indicate that when an Object is compared to a Number, the Object is converted to its original value. How is the original value obtained?

ToPrimitive is a built-in Symbol value that exists as a function value attribute of the object. This function is called when an object is converted to its original value. If Symbol. ToPrimitive does not return a valueOf the basic type, the object’s valueOf() method is called first to get a value to manipulate, and if the value is NaN, then toString() is called finally to get the original value.

From all this, we should be able to write at least two answers to the question:

Answer a:

var a = {
    i: 1.valueOf: function () {
        return this.i++; }}console.log(a == 1 && a == 2 && a == 3); // true
Copy the code

Answer 2:

var a = {
    i: 1.toString: function () {
        return this.i++; }}console.log(a == 1 && a == 2 && a == 3); // true
Copy the code

Symbol. ToPrimitive: Symbol. ToPrimitive: Symbol.

Answer three:

var a = {
    i: 1[Symbol.toPrimitive]: function (hint) {
        return this.i++; }}console.log(a == 1 && a == 2 && a == 3); // true
// Symbol. ToPrimitive has the highest priority in valueOf and toString()
Copy the code

The toString() method is also used to convert an array to a string (because the array is called valueOf() and returns its own value), and the toString() method joins an array, so:

Answer 4:

var a = [1.2.3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3); // true
// The shift method removes the first item of the array, returning the deleted element and changing the array.
Copy the code

There are actually two other ways to solve this problem, but I want to record implicit conversions this time, so I won’t go too far.

However, post the answers for a note:

  • Define a property and override its getter method:
const value = function* () {
  let i = 0;
  while(true) yield++i; } ();Object.defineProperty(this.'a', {
  get() {
    returnvalue.next().value; }});console.log(a == 1 && a == 2 && a == 3); // true
Copy the code
  • Using Unicode character encodings: Synonymous and invisible characters:
var a = 1;
var a‌ = 2;
var a‍ = 3;
console.log(a == 1 && a‌ == 2 && a‍ == 3);
/**** var a = 1; var a\u200c = 2; var a\u200d = 3; console.log(a == 1 && a\u200c == 2 && a\u200d == 3); * * * * /
Copy the code