Hướng dẫn should i use double equals in javascript? - tôi có nên sử dụng dấu bằng kép trong javascript không?

Ngày 3 tháng 8 năm 2020

Không giống như nhiều ngôn ngữ lập trình khác JavaScript có cả hai bằng kép bằng == và ba bằng toán tử so sánh ===. Thoạt nhìn, họ dường như làm gần như chính xác điều tương tự, nhưng có một sự khác biệt lớn giữa hai điều làm cho Triple bằng hầu như luôn luôn tốt hơn.

Nếu bạn thích học trực quan, hãy xem phiên bản video của bài viết này.

Điều gì làm cho chúng khác biệt

Cả hai và ba bằng nhau sẽ kiểm tra sự bình đẳng của hai giá trị và trả về đúng hay sai tùy thuộc vào việc chúng bằng hay không, nhưng cách chúng thực hiện kiểm tra bình đẳng đó hơi khác nhau. Với bằng kép bằng, JavaScript sẽ chuyển đổi các loại của hai giá trị giống hệt nhau trước khi thực hiện kiểm tra bình đẳng. Điều này có nghĩa là nếu bạn có mã sau 1 == '1' thì JavaScript sẽ chuyển đổi chuỗi

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
0 thành một số để kiểm tra bình đẳng là so sánh hai số. Điều này sẽ dẫn đến mã trước đó trả về true vì số một bằng với chuỗi sau khi nó được chuyển đổi thành một số.

Với ba bằng nhau, chuyển đổi các loại này không xảy ra. Điều đó có nghĩa là nếu chúng ta sử dụng cùng một mã như trước đây nhưng với một so sánh bằng ba, chúng ta sẽ nhận được sai

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
1. Điều này là do chuỗi
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
0 không được chuyển đổi thành một số và do đó, khi tính bình đẳng của số một được so sánh với chuỗi, nó trả về sai vì một chuỗi không bao giờ bằng một số.

Tại sao nó quan trọng

Có vẻ như bằng kép là phương pháp ưa thích để kiểm tra bình đẳng vì nó thực hiện chuyển đổi loại cho bạn và nhiều khả năng khi bạn đang so sánh

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
3 và
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
0 mà bạn có nghĩa là cả hai đều là số. Trong thực tế, mặc dù, đây thực sự là một ý tưởng khủng khiếp.

Vấn đề là điều này có thể dẫn đến nhiều dương tính giả. Ví dụ: lấy mã sau.

Rõ ràng, số 0 không bằng một chuỗi trống, vì vậy chúng tôi hy vọng điều này sẽ trả về sai, nhưng nó thực sự trả về đúng. Điều này là do JavaScript đang cố gắng chuyển đổi chuỗi trống thành một số và chuyển đổi nó thành số 0. Điều này có thể dẫn đến một tấn các vấn đề tiềm năng. Ví dụ: giả sử bạn có một phần tử đầu vào mà người dùng nhập và bạn muốn kiểm tra xem họ có gõ bằng không. Nếu bạn sử dụng mã trước đó cho kiểm tra đó, nó sẽ trả về đúng bất cứ khi nào chúng nhập 0 và bất cứ khi nào đầu vào trống, điều này không lý tưởng. Tuy nhiên, điều này có thể tránh được với ba bằng ba, vì bất cứ khi nào các loại giá trị khác nhau ba bằng nhau sẽ trả về sai.

Khi nào nên sử dụng kép bằng

Vì vậy, có vẻ như bằng kép là khủng khiếp và không bao giờ nên được sử dụng do có thể dương tính giả có thể, nhưng có một trường hợp đặc biệt là tôi thấy bằng kép là vô cùng hữu ích. Tình huống đó là khi bạn cần kiểm tra các giá trị null/không xác định. Nếu bạn so sánh NULL và không xác định với đôi bằng nhau, nó sẽ trả về true, nhưng với ba bằng, nó sẽ trả về sai.

Nhiều lần khi tôi đang cố gắng kiểm tra một biến để xem liệu nó có phải là không, tôi cũng muốn kiểm tra xem nó có được xác định cùng một lúc không. Bởi vì điều này, tôi hầu như luôn sử dụng kép bằng để so sánh với null/không xác định vì nó sẽ trả về đúng nếu giá trị của tôi là null hoặc không xác định.

Sự kết luận

Trong 99% trong số tất cả các trường hợp, bạn nên sử dụng so sánh ba lần khi so sánh hai giá trị để tránh dương tính giả, nhưng nếu bạn đang cố gắng kiểm tra xem một vales có null/không xác định thì sử dụng bằng kép là phương pháp ưa thích không.

JavaScript cung cấp ba hoạt động so sánh giá trị khác nhau:

  • === - Bình đẳng nghiêm ngặt (ba bằng)
  • == - Bình đẳng lỏng lẻo (bằng kép)
  • console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN: console.log("Surprise"); // Nothing is logged
    }
    
    7

Hoạt động nào bạn chọn phụ thuộc vào loại so sánh bạn đang tìm kiếm để thực hiện. Tóm tắt:

  • Double bằng (==) sẽ thực hiện chuyển đổi loại khi so sánh hai điều và sẽ xử lý
    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN: console.log("Surprise"); // Nothing is logged
    }
    
    9,
    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    
    0 và
    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    
    1 đặc biệt để phù hợp với IEEE 754 (vì vậy
    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    
    2 và
    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    
    3);
  • Triple Equals (===) sẽ thực hiện so sánh tương tự như bằng kép (bao gồm cả việc xử lý đặc biệt cho
    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN: console.log("Surprise"); // Nothing is logged
    }
    
    9,
    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    
    0 và
    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    
    1) nhưng không chuyển đổi loại; Nếu các loại khác nhau,
    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    
    8 được trả về.
  • console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN: console.log("Surprise"); // Nothing is logged
    }
    
    7 không chuyển đổi loại và không có khả năng xử lý đặc biệt cho
    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN: console.log("Surprise"); // Nothing is logged
    }
    
    9,
    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    
    0 và
    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    
    1 (mang lại cho nó hành vi tương tự như === ngoại trừ trên các giá trị số đặc biệt đó).

Chúng tương ứng với ba trong số bốn thuật toán bình đẳng trong JavaScript:

  • Islooselyequal: ==
  • ISSTRICTIGNEQUAL: ===
  • SHOVALUE:
    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN: console.log("Surprise"); // Nothing is logged
    }
    
    7
  • SameValuezero: Được sử dụng bởi nhiều hoạt động tích hợp

Lưu ý rằng sự khác biệt giữa tất cả những điều này phải làm với việc xử lý các nguyên thủy của họ; Không ai trong số họ so sánh liệu các tham số có giống nhau về mặt cấu trúc hay không. Đối với bất kỳ đối tượng không nguyên thủy nào

// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
7 và
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
8 có cùng cấu trúc nhưng là các đối tượng riêng biệt, tất cả các hình thức trên sẽ đánh giá thành
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
8.

Bình đẳng nghiêm ngặt bằng cách sử dụng ===

Bình đẳng nghiêm ngặt so sánh hai giá trị cho sự bình đẳng. Không giá trị nào được chuyển đổi hoàn toàn thành một số giá trị khác trước khi được so sánh. Nếu các giá trị có các loại khác nhau, các giá trị được coi là không đồng đều. Nếu các giá trị có cùng loại, không phải là số và có cùng một giá trị, chúng được coi là bằng nhau. Cuối cùng, nếu cả hai giá trị là số, chúng được coi là bằng nhau nếu cả hai đều không

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9 và là cùng một giá trị hoặc nếu một là
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
1 và một là
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0.

const num = 0;
const obj = new String("0");
const str = "0";

console.log(num === num); // true
console.log(obj === obj); // true
console.log(str === str); // true

console.log(num === obj); // false
console.log(num === str); // false
console.log(obj === str); // false
console.log(null === undefined); // false
console.log(obj === null); // false
console.log(obj === undefined); // false

Bình đẳng nghiêm ngặt hầu như luôn luôn là hoạt động so sánh chính xác để sử dụng. Đối với tất cả các giá trị ngoại trừ các số, nó sử dụng ngữ nghĩa rõ ràng: một giá trị chỉ bằng với chính nó. Đối với các con số, nó sử dụng ngữ nghĩa hơi khác nhau để đánh bóng qua hai trường hợp cạnh khác nhau. Đầu tiên là điểm nổi bằng 0 là có dấu tích cực hoặc tiêu cực. Điều này rất hữu ích trong việc thể hiện các giải pháp toán học nhất định, nhưng vì hầu hết các tình huống không quan tâm đến sự khác biệt giữa

const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
1 và
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0, sự bình đẳng nghiêm ngặt coi chúng là cùng một giá trị. Thứ hai là điểm nổi bao gồm khái niệm về giá trị không phải là một số,
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9, để thể hiện giải pháp cho một số vấn đề toán học không xác định: vô cực tiêu cực được thêm vào vô cùng dương tính. Bình đẳng nghiêm ngặt coi
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9 là không đồng đều với mọi giá trị khác - bao gồm cả chính nó. (Trường hợp duy nhất trong đó
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
7 là
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8 là khi
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
7 là
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9.)

Bên cạnh ===, sự bình đẳng nghiêm ngặt cũng được sử dụng bởi các phương pháp tìm chỉ số mảng bao gồm

const stoppingForce = obj.mass * -obj.velocity;
2,
const stoppingForce = obj.mass * -obj.velocity;
3,
const stoppingForce = obj.mass * -obj.velocity;
4,
const stoppingForce = obj.mass * -obj.velocity;
5 và ________ 56-phù hợp. Điều này có nghĩa là bạn không thể sử dụng
const stoppingForce = obj.mass * -obj.velocity;
7 để tìm chỉ số của giá trị
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9 trong một mảng hoặc sử dụng
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9 làm giá trị
const stoppingForce = obj.mass * -obj.velocity;
6 trong câu lệnh
const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer);
const b2f = (x) => new Float64Array(x.buffer)[0];
// Get a byte representation of NaN
const n = f2b(NaN);
// Change the first bit, which is the sign bit and doesn't matter for NaN
n[0] = 1;
const nan2 = b2f(n);
console.log(nan2); // NaN
console.log(Object.is(nan2, NaN)); // true
console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
console.log(f2b(nan2)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127]
1 và làm cho nó phù hợp với bất cứ điều gì.

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}

Bình đẳng lỏng lẻo bằng cách sử dụng ==

Bình đẳng lỏng lẻo là đối xứng:

const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer);
const b2f = (x) => new Float64Array(x.buffer)[0];
// Get a byte representation of NaN
const n = f2b(NaN);
// Change the first bit, which is the sign bit and doesn't matter for NaN
n[0] = 1;
const nan2 = b2f(n);
console.log(nan2); // NaN
console.log(Object.is(nan2, NaN)); // true
console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
console.log(f2b(nan2)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127]
2 luôn có ngữ nghĩa giống hệt nhau với
const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer);
const b2f = (x) => new Float64Array(x.buffer)[0];
// Get a byte representation of NaN
const n = f2b(NaN);
// Change the first bit, which is the sign bit and doesn't matter for NaN
n[0] = 1;
const nan2 = b2f(n);
console.log(nan2); // NaN
console.log(Object.is(nan2, NaN)); // true
console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
console.log(f2b(nan2)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127]
3 cho bất kỳ giá trị nào của
const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer);
const b2f = (x) => new Float64Array(x.buffer)[0];
// Get a byte representation of NaN
const n = f2b(NaN);
// Change the first bit, which is the sign bit and doesn't matter for NaN
n[0] = 1;
const nan2 = b2f(n);
console.log(nan2); // NaN
console.log(Object.is(nan2, NaN)); // true
console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
console.log(f2b(nan2)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127]
4 và
const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer);
const b2f = (x) => new Float64Array(x.buffer)[0];
// Get a byte representation of NaN
const n = f2b(NaN);
// Change the first bit, which is the sign bit and doesn't matter for NaN
n[0] = 1;
const nan2 = b2f(n);
console.log(nan2); // NaN
console.log(Object.is(nan2, NaN)); // true
console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
console.log(f2b(nan2)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127]
5 (ngoại trừ thứ tự chuyển đổi ứng dụng). Hành vi để thực hiện bình đẳng lỏng lẻo bằng cách sử dụng == như sau:

  1. Nếu các toán hạng có cùng loại, chúng được so sánh như sau:
    • Đối tượng: Trả về
      function sameValueZero(x, y) {
        if (typeof x === "number" && typeof y === "number") {
          // x and y are equal (may be -0 and 0) or they are both NaN
          return x === y || (x !== x && y !== y);
        }
        return x === y;
      }
      
      8 chỉ khi cả hai toán hạng tham chiếu cùng một đối tượng.
    • Chuỗi: Trả về
      function sameValueZero(x, y) {
        if (typeof x === "number" && typeof y === "number") {
          // x and y are equal (may be -0 and 0) or they are both NaN
          return x === y || (x !== x && y !== y);
        }
        return x === y;
      }
      
      8 chỉ khi cả hai toán hạng có cùng ký tự theo cùng một thứ tự.
    • Số: Trả về
      function sameValueZero(x, y) {
        if (typeof x === "number" && typeof y === "number") {
          // x and y are equal (may be -0 and 0) or they are both NaN
          return x === y || (x !== x && y !== y);
        }
        return x === y;
      }
      
      8 chỉ khi cả hai toán hạng có cùng giá trị.
      const num = 0;
      const big = 0n;
      const str = "0";
      const obj = new String("0");
      
      console.log(num == str); // true
      console.log(big == num); // true
      console.log(str == big); // true
      
      console.log(num == obj); // true
      console.log(big == obj); // true
      console.log(str == obj); // true
      
      1 và
      const num = 0;
      const big = 0n;
      const str = "0";
      const obj = new String("0");
      
      console.log(num == str); // true
      console.log(big == num); // true
      console.log(str == big); // true
      
      console.log(num == obj); // true
      console.log(big == obj); // true
      console.log(str == obj); // true
      
      0 được coi là cùng một giá trị. Nếu một trong hai toán hạng là
      console.log([NaN].indexOf(NaN)); // -1
      switch (NaN) {
        case NaN: console.log("Surprise"); // Nothing is logged
      }
      
      9, hãy trả về
      const num = 0;
      const big = 0n;
      const str = "0";
      const obj = new String("0");
      
      console.log(num == str); // true
      console.log(big == num); // true
      console.log(str == big); // true
      
      console.log(num == obj); // true
      console.log(big == obj); // true
      console.log(str == obj); // true
      
      8; Vì vậy,
      console.log([NaN].indexOf(NaN)); // -1
      switch (NaN) {
        case NaN: console.log("Surprise"); // Nothing is logged
      }
      
      9 không bao giờ bằng
      console.log([NaN].indexOf(NaN)); // -1
      switch (NaN) {
        case NaN: console.log("Surprise"); // Nothing is logged
      }
      
      9.
    • Boolean: Trả về
      function sameValueZero(x, y) {
        if (typeof x === "number" && typeof y === "number") {
          // x and y are equal (may be -0 and 0) or they are both NaN
          return x === y || (x !== x && y !== y);
        }
        return x === y;
      }
      
      8 chỉ khi toán hạng là
      function sameValueZero(x, y) {
        if (typeof x === "number" && typeof y === "number") {
          // x and y are equal (may be -0 and 0) or they are both NaN
          return x === y || (x !== x && y !== y);
        }
        return x === y;
      }
      
      8 hoặc cả
      const num = 0;
      const big = 0n;
      const str = "0";
      const obj = new String("0");
      
      console.log(num == str); // true
      console.log(big == num); // true
      console.log(str == big); // true
      
      console.log(num == obj); // true
      console.log(big == obj); // true
      console.log(str == obj); // true
      
      8.
    • BIGINT: Trả về
      function sameValueZero(x, y) {
        if (typeof x === "number" && typeof y === "number") {
          // x and y are equal (may be -0 and 0) or they are both NaN
          return x === y || (x !== x && y !== y);
        }
        return x === y;
      }
      
      8 chỉ khi cả hai toán hạng có cùng giá trị.
    • Biểu tượng: Trả về
      function sameValueZero(x, y) {
        if (typeof x === "number" && typeof y === "number") {
          // x and y are equal (may be -0 and 0) or they are both NaN
          return x === y || (x !== x && y !== y);
        }
        return x === y;
      }
      
      8 chỉ khi cả hai toán hạng tham chiếu cùng một ký hiệu.
  2. Nếu một trong các toán hạng là ===1 hoặc ===2, thì cái còn lại cũng phải là ===1 hoặc ===2 để trả lại
    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    
    8. Nếu không, hãy trả lại
    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    
    8.
  3. Nếu một trong các toán hạng là một đối tượng và người kia là nguyên thủy, hãy chuyển đổi đối tượng thành nguyên thủy.
  4. Ở bước này, cả hai toán hạng được chuyển đổi thành nguyên thủy (một chuỗi, số, boolean, biểu tượng và bigint). Phần còn lại của chuyển đổi được thực hiện từng trường hợp.
    • Nếu chúng cùng loại, hãy so sánh chúng bằng cách sử dụng bước 1.
    • Nếu một trong các toán hạng là một biểu tượng nhưng bản kia thì không, hãy trả lại
      const num = 0;
      const big = 0n;
      const str = "0";
      const obj = new String("0");
      
      console.log(num == str); // true
      console.log(big == num); // true
      console.log(str == big); // true
      
      console.log(num == obj); // true
      console.log(big == obj); // true
      console.log(str == obj); // true
      
      8.
    • Nếu một trong các toán hạng là boolean nhưng cái còn lại thì không, hãy chuyển đổi boolean thành một số:
      function sameValueZero(x, y) {
        if (typeof x === "number" && typeof y === "number") {
          // x and y are equal (may be -0 and 0) or they are both NaN
          return x === y || (x !== x && y !== y);
        }
        return x === y;
      }
      
      8 được chuyển đổi thành 1 và
      const num = 0;
      const big = 0n;
      const str = "0";
      const obj = new String("0");
      
      console.log(num == str); // true
      console.log(big == num); // true
      console.log(str == big); // true
      
      console.log(num == obj); // true
      console.log(big == obj); // true
      console.log(str == obj); // true
      
      8 được chuyển đổi thành 0. sau đó so sánh hai toán hạng một lần nữa.
    • Số thành chuỗi: Chuyển đổi chuỗi thành một số. Lỗi chuyển đổi dẫn đến
      console.log([NaN].indexOf(NaN)); // -1
      switch (NaN) {
        case NaN: console.log("Surprise"); // Nothing is logged
      }
      
      9, sẽ đảm bảo sự bình đẳng là
      const num = 0;
      const big = 0n;
      const str = "0";
      const obj = new String("0");
      
      console.log(num == str); // true
      console.log(big == num); // true
      console.log(str == big); // true
      
      console.log(num == obj); // true
      console.log(big == obj); // true
      console.log(str == obj); // true
      
      8.
    • Số với Bigint: So sánh bằng giá trị số của chúng. Nếu số là ± vô cực hoặc
      console.log([NaN].indexOf(NaN)); // -1
      switch (NaN) {
        case NaN: console.log("Surprise"); // Nothing is logged
      }
      
      9, hãy trả về
      const num = 0;
      const big = 0n;
      const str = "0";
      const obj = new String("0");
      
      console.log(num == str); // true
      console.log(big == num); // true
      console.log(str == big); // true
      
      console.log(num == obj); // true
      console.log(big == obj); // true
      console.log(str == obj); // true
      
      8.
    • Chuỗi thành Bigint: Chuyển đổi chuỗi thành Bigint bằng cách sử dụng cùng một thuật toán với hàm tạo 1 == '1'4. Nếu chuyển đổi thất bại, trả về
      const num = 0;
      const big = 0n;
      const str = "0";
      const obj = new String("0");
      
      console.log(num == str); // true
      console.log(big == num); // true
      console.log(str == big); // true
      
      console.log(num == obj); // true
      console.log(big == obj); // true
      console.log(str == obj); // true
      
      8.

Theo truyền thống, và theo Ecmascript, tất cả các nguyên thủy và đối tượng đều không đồng đều với ===2 và ===1. Nhưng hầu hết các trình duyệt cho phép một lớp đối tượng rất hẹp (cụ thể là đối tượng 1 == '1'8 cho bất kỳ trang nào), trong một số bối cảnh, hành động như thể chúng mô phỏng giá trị ===2. Bình đẳng lỏng lẻo là một trong những bối cảnh như vậy:

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
00 và
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
01 đánh giá đúng nếu, và chỉ khi, A là một đối tượng mô phỏng ===2. Trong tất cả các trường hợp khác, một đối tượng không bao giờ lỏng lẻo bằng ===2 hoặc ===1.

Trong hầu hết các trường hợp, sử dụng bình đẳng lỏng lẻo là không được khuyến khích. Kết quả của việc so sánh sử dụng bình đẳng nghiêm ngặt dễ dự đoán hơn và có thể đánh giá nhanh hơn do thiếu sự ép buộc loại.

Ví dụ sau đây cho thấy các so sánh bình đẳng lỏng lẻo liên quan đến số nguyên thủy

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
05, nguyên thủy lớn
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
06, chuỗi nguyên thủy
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
07 và một đối tượng có giá trị ____108 là
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
07.

const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true

Bình đẳng lỏng lẻo chỉ được sử dụng bởi toán tử ==.

Bình đẳng có giá trị bằng cách sử dụng Object.is ()

Bình đẳng cùng giá trị xác định xem hai giá trị có giống hệt nhau về mặt chức năng trong tất cả các bối cảnh hay không. (Trường hợp sử dụng này thể hiện một ví dụ về nguyên tắc thay thế Liskov.)

// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
11 sẽ ném một ngoại lệ khi cố gắng thay đổi một tài sản bất biến, nhưng nó không làm gì nếu không có thay đổi thực tế được yêu cầu. Nếu
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
12 là
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0, không có thay đổi nào được yêu cầu và sẽ không có lỗi nào. Trong nội bộ, khi một thuộc tính bất biến được xác định lại, giá trị mới được chỉ định được so sánh với giá trị hiện tại sử dụng bình đẳng có giá trị.

Bình đẳng cùng giá trị được cung cấp theo phương pháp

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
14. Nó được sử dụng hầu hết mọi nơi trong ngôn ngữ nơi dự kiến ​​giá trị của bản sắc tương đương.

Bình đẳng cùng giá trị

Tương tự như bình đẳng có giá trị, nhưng +0 và -0 được coi là bằng nhau.

Bình đẳng cùng giá trị không được phơi bày dưới dạng API JavaScript, nhưng có thể được triển khai bằng mã tùy chỉnh:

function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}

Cùng một giá trị-Zero chỉ khác với bình đẳng nghiêm ngặt bằng cách coi

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9 là tương đương và chỉ khác với bình đẳng có giá trị bằng cách coi
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0 là tương đương với
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
05. Điều này làm cho nó thường có hành vi hợp lý nhất trong khi tìm kiếm, đặc biệt là khi làm việc với
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9. Nó được sử dụng bởi
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
19,
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
20, cũng như các phương pháp
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
21 và
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
22 để so sánh bình đẳng chính.

So sánh các phương pháp bình đẳng

Mọi người thường so sánh bằng kép và ba bằng cách nói một là phiên bản "nâng cao" của phiên bản kia. Ví dụ, Double Equals có thể được nói như là một phiên bản mở rộng của Triple Equals, bởi vì cái trước làm mọi thứ mà sau này làm, nhưng với chuyển đổi loại trên các toán hạng của nó - ví dụ,

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
23. Ngoài ra, có thể tuyên bố rằng Double Equals là đường cơ sở và Triple Equals là phiên bản nâng cao, bởi vì nó đòi hỏi hai toán hạng phải là cùng một loại, do đó, nó thêm một ràng buộc bổ sung.

Tuy nhiên, cách suy nghĩ này ngụ ý rằng các so sánh bình đẳng tạo thành một "quang phổ" một chiều trong đó "hoàn toàn nghiêm ngặt" nằm ở một đầu và "hoàn toàn lỏng lẻo" nằm ở đầu kia. Mô hình này bị thiếu với

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
14, bởi vì nó không "lỏng hơn" so với bằng kép hoặc "nghiêm ngặt" so với ba bằng, cũng không phù hợp ở đâu đó ở giữa (tức là, cả hai chặt chẽ hơn gấp đôi, nhưng lỏng hơn ba bằng nhau). Chúng ta có thể thấy từ bảng so sánh giống nhau bên dưới rằng điều này là do cách mà
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
14 xử lý
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9. Lưu ý rằng nếu
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
27 được đánh giá là
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
8, chúng ta có thể nói rằng nó phù hợp với phổ lỏng lẻo/nghiêm ngặt như một dạng ba của ba bằng nhau, một hình thức phân biệt giữa
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0 và
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
1. Tuy nhiên, việc xử lý
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9 có nghĩa là điều này là không đúng sự thật. Thật không may,
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
14 phải được suy nghĩ về các đặc điểm cụ thể của nó, thay vì sự lỏng lẻo hoặc nghiêm ngặt của nó liên quan đến các nhà khai thác bình đẳng.

xy=====
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
14
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
36
===2===2
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
8
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
8
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1===1
===1===2
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
===1===1===1
===1===1===1===1===1===1
===2===1===1===1===1===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
===1===1===1===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
===1===1===1===1
===1===1===1===1===1===1
===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
===1===1===1===1
===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
===1===1===1===1
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // x and y are equal (may be -0 and 0) or they are both NaN
    return x === y || (x !== x && y !== y);
  }
  return x === y;
}
8
===1===1
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
39

function sameValueZero(x, y) { if (typeof x === "number" && typeof y === "number") { // x and y are equal (may be -0 and 0) or they are both NaN return x === y || (x !== x && y !== y); } return x === y; } 8

const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
8

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
61

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
05

const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
1

const stoppingForce = obj.mass * -obj.velocity;

const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0

// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
09,
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
10,
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
11,
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
12

Trong một số trường hợp,

const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0 có thể được đưa vào biểu thức như là giá trị trả về của các phương thức này ngay cả khi không có
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0 tồn tại dưới dạng một trong các tham số. Ví dụ, sử dụng
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
11 để nâng
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
16 lên sức mạnh của bất kỳ số mũ tiêu cực, kỳ lạ nào đánh giá thành
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0. Tham khảo tài liệu cho các phương pháp riêng lẻ.

// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
18,
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
19,
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
20,
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
21,
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
22,
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
23

Có thể nhận được giá trị trả về

const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0 trong số các phương thức này trong một số trường hợp tồn tại
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0 dưới dạng một trong các tham số. Ví dụ:
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
26 đánh giá thành
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0. Tham khảo tài liệu cho các phương pháp riêng lẻ.

// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
28,
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
29,
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
30

Mỗi toán tử này sử dụng thuật toán TOINT32 bên trong. Vì chỉ có một đại diện cho 0 trong loại số nguyên 32 bit bên trong,

const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0 sẽ không tồn tại một chuyến đi khứ hồi sau khi hoạt động nghịch đảo. Ví dụ: cả
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
32 và
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false,
});

function attemptMutation(v) {
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
33 đánh giá thành
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
8.

Dựa vào

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
14 khi tính ký của số không được tính đến có thể gây nguy hiểm. Tất nhiên, khi ý định là phân biệt giữa
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
0 và
const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");

console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true

console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true
1, nó sẽ thực hiện chính xác những gì mong muốn.

Hãy cẩn thận: Object.is () và Nan

Đặc tả

console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
14 coi tất cả các trường hợp của
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9 là cùng một đối tượng. Tuy nhiên, vì các mảng được đánh máy có sẵn, chúng ta có thể có các biểu diễn điểm nổi riêng biệt của
console.log([NaN].indexOf(NaN)); // -1
switch (NaN) {
  case NaN: console.log("Surprise"); // Nothing is logged
}
9 không hoạt động giống hệt nhau trong tất cả các bối cảnh. Ví dụ:

const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer);
const b2f = (x) => new Float64Array(x.buffer)[0];
// Get a byte representation of NaN
const n = f2b(NaN);
// Change the first bit, which is the sign bit and doesn't matter for NaN
n[0] = 1;
const nan2 = b2f(n);
console.log(nan2); // NaN
console.log(Object.is(nan2, NaN)); // true
console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
console.log(f2b(nan2)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127]

Xem thêm

Bạn có nên sử dụng đôi bằng trong JavaScript không?

Trong 99% trong số tất cả các trường hợp, bạn nên sử dụng so sánh ba lần khi so sánh hai giá trị để tránh dương tính giả, nhưng nếu bạn đang cố gắng kiểm tra xem một vales có null/không xác định thì sử dụng bằng kép là phương pháp ưa thích không.if you are attempting to check if a vales is null/undefined then using double equals is the preferred method.

Tôi nên sử dụng kép hay ba bằng JavaScript?

Triple Equals là vượt trội so với bằng kép. Bất cứ khi nào có thể, bạn nên sử dụng ba bằng để kiểm tra bình đẳng. Bằng cách kiểm tra loại và giá trị, bạn có thể chắc chắn rằng bạn luôn thực hiện một bài kiểm tra bình đẳng thực sự.. Whenever possible, you should use triple equals to test equality. By testing the type and value you can be sure that you are always executing a true equality test.

Tôi có nên sử dụng == hoặc === trong JavaScript không?

= Vs == vs === Trong javascript = trong javaScript được sử dụng để gán các giá trị cho một biến.== Trong JavaScript được sử dụng để so sánh hai biến, nhưng nó bỏ qua kiểu dữ liệu của biến.=== được sử dụng để so sánh hai biến, nhưng toán tử này cũng kiểm tra kiểu dữ liệu và so sánh hai giá trị.== in JavaScript is used for comparing two variables, but it ignores the datatype of variable. === is used for comparing two variables, but this operator also checks datatype and compares two values.

Có nghĩa là gì trong JavaScript?

Toán tử bình đẳng (==) kiểm tra xem hai toán hạng của nó có bằng nhau hay không, trả về kết quả boolean.Không giống như toán tử bình đẳng nghiêm ngặt, nó cố gắng chuyển đổi và so sánh các toán hạng có các loại khác nhau.checks whether its two operands are equal, returning a Boolean result. Unlike the strict equality operator, it attempts to convert and compare operands that are of different types.