Object.is vs ===


141

Tôi tình cờ thấy một ví dụ mã đang sử dụng so sánh này:

var someVar = 0;
Object.is(false, someVar); //Returns false 

Tôi biết đó false == 0sẽ là truelý do tại sao chúng ta có ===.

Làm thế nào Object.iskhác với ===?

Câu trả lời:


174

===được gọi là toán tử so sánh nghiêm ngặt trong JavaScript. Object.isvà toán tử so sánh nghiêm ngặt hành xử giống hệt nhau ngoại trừ NaN+0/-0.

Từ MDN:

Object.is()phương pháp không giống như bằng nhau theo ===toán tử. Các ===nhà điều hành (và các ==nhà điều hành cũng) xử lý các giá trị số -0 và +0 như bình đẳng và đối xử Number.NaNnhư không bằng NaN.

Mã dưới đây nêu bật sự khác biệt giữa ===Object.is().

console.log(+0 === -0); //true
console.log(Object.is(+0, -0)); //false

console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); //true

console.log(Number.NaN === Number.NaN); // false
console.log(Object.is(Number.NaN, Number.NaN)); // true

console.log(NaN === Number.NaN); // false
console.log(Object.is(NaN, Number.NaN)); // true

nhập mô tả hình ảnh ở đây

Bạn có thể tìm thấy nhiều ví dụ ở đây .

Lưu ý : Object.islà một phần của đề xuất ECMAScript 6 và chưa được hỗ trợ rộng rãi (ví dụ: nó không được hỗ trợ bởi bất kỳ phiên bản Internet Explorer hoặc nhiều phiên bản cũ hơn của các trình duyệt khác). Tuy nhiên, bạn có thể sử dụng một polyfill cho các trình duyệt không phải ES6 có thể được tìm thấy trong liên kết được đưa ra ở trên.


26
Dòng đầu tiên của câu trả lời phải là "Chúng hoạt động giống hệt nhau ngoại trừ NaN và +0 và -0", có lẽ.
Benjamin Gruenbaum

1
@BenjaminGruenbaum Gợi ý tốt. Làm cho câu trả lời dễ đọc hơn. Chúc mừng.
Gurpreet Singh

3
@ humble.rumble điều này đã được thảo luận dài - phương pháp tĩnh đơn giản hơn - chúng không có vấn đề bối cảnh hoặc vấn đề nguyên thủy. Ví dụ trong ví dụ của bạn, tôi mong đợi sai nhưng những người mới biết về JS sẽ mong đợi đúng vì thực hiện .xtrên một chuỗi chuỗi nó thành một Stringđối tượng (chứ không phải giá trị nguyên thủy của chuỗi) và so sánh sẽ là giữa một đối tượng và chuỗi - điều này rất tinh tế và là một cạm bẫy - statics tránh những vấn đề này, phương pháp tĩnh đơn giản hơn và dễ sử dụng hơn.
Benjamin Gruenbaum

2
@ humble.rumble Để so sánh các nút DOM, đã có một phương thức như vậy, xem isEqualNode . Ví dụ:document.createElement('div').isEqualNode(document.createElement('div')) === true
Rob W

2
Cập nhật 2017: Object.is () hiện được hỗ trợ rộng rãi trong tất cả các trình duyệt chính.
Sterling Bourne

56

Object.issử dụng thuật toán SameValue của đặc tả , trong khi ===sử dụng Thuật toán bình đẳng nghiêm ngặt . Một lưu ý về Thuật toán bình đẳng nghiêm ngặt gọi ra sự khác biệt:

Thuật toán này khác với Thuật toán SameValue ... trong cách xử lý các số 0 và NaN đã ký.

Lưu ý rằng:

  • NaN === NaNlà sai, nhưng Object.is(NaN, NaN)là đúng
  • +0 === -0là đúng, nhưng Object.is(+0, -0)là sai
  • -0 === +0là đúng, nhưng Object.is(-0, +0)là sai

JavaScript có ít nhất bốn loại "bình đẳng":

  • "Loose" ( ==), trong đó các toán hạng sẽ được ép buộc để cố gắng làm cho chúng khớp. Các quy tắc được chỉ định rõ ràng , nhưng không rõ ràng. ( "" == 0true; "true" == truefalse, ...).
  • "Nghiêm" ( ===), trong đó các toán hạng thuộc các loại khác nhau sẽ không bị ép buộc (và sẽ không bằng nhau), nhưng xem ghi chú ở trên về NaNvà số 0 dương và âm.
  • SameValue - như được liệt kê ở trên (được sử dụng bởi Object.is).
  • SameValueZero - giống như SameValuengoại trừ +0-0giống nhau thay vì khác nhau (được sử dụng Mapcho các phím và bởi Array.prototype.includes).

Ngoài ra còn có sự tương đương đối tượng , không được cung cấp bởi chính ngôn ngữ hoặc thời gian chạy, nhưng thường được biểu thị là: Các đối tượng có cùng nguyên mẫu, cùng thuộc tính và giá trị thuộc tính của chúng là như nhau (theo một định nghĩa hợp lý về "giống nhau" ).


Thuật toán SameValue :

  • Nếu Loại (x) khác với Loại (y), hãy trả về false.
  • Nếu Loại (x) là Số, thì
    • Nếu x là NaN và y là NaN, trả về true.
    • Nếu x là +0 và y là -0, trả về false.
    • Nếu x là -0 và y là +0, trả về false.
    • Nếu x là giá trị Số giống như y, trả về true.
    • Trả lại sai.
  • Trả về SameValueNonNumber (x, y).

... Trong đó SameValueNonNumber là:

  • Khẳng định: Loại (x) không phải là Số.
  • Khẳng định: Loại (x) giống như Loại (y).
  • Nếu Loại (x) không xác định, trả về true.
  • Nếu Loại (x) là Null, trả về true.
  • Nếu Loại (x) là Chuỗi, thì
    • Nếu x và y chính xác là cùng một chuỗi các đơn vị mã (cùng độ dài và cùng đơn vị mã tại các chỉ số tương ứng), trả về true; nếu không, trả lại sai.
  • Nếu Loại (x) là Boolean, thì
    • Nếu x và y đều đúng hoặc cả sai, trả về true; nếu không, trả lại sai.
  • Nếu Loại (x) là Biểu tượng, thì
    • Nếu x và y đều có cùng giá trị Ký hiệu, trả về true; nếu không, trả lại sai.
  • Trả về true nếu x và y là cùng một giá trị Object. Nếu không, trả lại sai.

Thuật toán bình đẳng nghiêm ngặt :

  1. Nếu Loại (x) khác với Loại (y), hãy trả về false.
  2. Nếu Loại (x) là Số, thì
    • Nếu x là NaN, trả về false.
    • Nếu y là NaN, trả về false.
    • Nếu x là giá trị Số giống như y, trả về true.
    • Nếu x là +0 và y là -0, trả về true.
    • Nếu x là -0 và y là +0, trả về true.
    • Trả lại sai.
  3. Trả về SameValueNonNumber (x, y).

2

Object.is = function(v1, v2){
  //test for `-0`
  if(v1 === 0 && v2 === 0) {
    return 1 / v1 === 1 / v2;
  }
  
  //test for `NaN`
  if(v1 !== v1) {
    return v2 !== v2;
  }
  
  //everything else
  return v1 === v2;
}

Trên đây là chức năng polyfill để hiển thị cách Object.ishoạt động, cho bất cứ ai quan tâm muốn biết. Tham chiếu đến You-Don't-know-JS


2

Tóm lược:

Các Object.is()chức năng mất 2 giá trị như các đối số và trả về true nếu 2 giá trị đưa ra là chính xác như nhau, nếu không nó sẽ trả về false.

Tại sao chúng ta cần điều này?

Bạn có thể nghĩ rằng, chúng ta đã có sự bình đẳng nghiêm ngặt (kiểm tra loại + giá trị) kiểm tra trong javascript với ===toán tử, tại sao chúng ta cần chức năng này? Bình đẳng nghiêm ngặt không đủ trong một số trường hợp và chúng là như sau:

console.log(NaN === NaN);   // false
console.log(-0 === +0);     // true

Object.is() giúp chúng tôi bằng cách có thể so sánh các giá trị này để xem chúng có giống nhau không, điều mà toán tử đẳng thức nghiêm ngặt không thể làm được.

console.log(Object.is(NaN, NaN));  // true
console.log(Object.is(-0, 0));     // false
console.log(Object.is(+0, +0));    // true
console.log(Object.is(+0, -0));    // false


0

Tóm lại, chúng tương tự nhau, nhưng Object.isthông minh hơn và chính xác hơn ...

Hãy nhìn vào điều này ...

+0 === -0 //true

Nhưng điều này không hoàn toàn đúng vì nó bỏ qua -+trước khi ...

Bây giờ chúng tôi sử dụng:

Object.is(+0, -0) //false

Như bạn thấy, điều này là chính xác hơn để so sánh.

Ngoài ra trong trường hợp NaNđó hoạt động giống như chính xác hơn, như xem xét bất kỳ NaNcùng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.