Object.is vs ===


141

ฉันสะดุดตัวอย่างรหัสซึ่งใช้การเปรียบเทียบนี้:

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

ฉันรู้ว่าfalse == 0จะเป็นนั่นเป็นเหตุผลที่เรามีtrue===

เป็นวิธีการที่Object.isแตกต่างจาก===?

คำตอบ:


174

===เรียกว่าโอเปอเรเตอร์การเปรียบเทียบที่เข้มงวดใน JavaScript Object.isและตัวดำเนินการเปรียบเทียบที่เข้มงวดจะทำงานเหมือนกันทุกประการยกเว้นNaNและ+0/-0

จาก MDN:

Object.is()วิธีการไม่เหมือนกับการเท่ากับตามตัว===ดำเนินการ ===ประกอบการ (และ==ผู้ประกอบการเช่นกัน) ถือว่าค่าจำนวน -0 และ 0 ที่เท่าเทียมกันและถือว่าเป็นไม่เท่ากับNumber.NaNNaN

โค้ดด้านล่างนี้ไฮไลท์ความแตกต่างระหว่างและ===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

ป้อนคำอธิบายรูปภาพที่นี่

คุณสามารถค้นหาตัวอย่างเพิ่มเติมที่นี่

หมายเหตุ : Object.isเป็นส่วนหนึ่งของข้อเสนอ ECMAScript 6 และยังไม่ได้รับการสนับสนุนอย่างกว้างขวาง (เช่นไม่ได้รับการสนับสนุนจาก Internet Explorer หรือเบราว์เซอร์อื่น ๆ ที่เก่ากว่า) อย่างไรก็ตามคุณสามารถใช้ polyfill สำหรับเบราว์เซอร์ที่ไม่ใช่ ES6 ซึ่งสามารถพบได้ในลิงค์ที่ให้ไว้ด้านบน


26
บรรทัดแรกของคำตอบควรเป็น "พวกมันทำงานเหมือนกันทุกประการยกเว้น NaN และ +0 และ -0"
Benjamin Gruenbaum

1
@BenjaminGruenbaum คำแนะนำที่ดี ทำให้คำตอบง่ายต่อการอ่าน ไชโย
Gurpreet Singh

3
@ humble.rumble นี้ถูกกล่าวถึงที่ความยาว - วิธีการแบบคงที่ง่ายกว่า - พวกเขาไม่มีปัญหาบริบทหรือปัญหาดั้งเดิม ตัวอย่างในตัวอย่างของคุณฉันคาดหวังว่าเป็นเท็จแต่มือใหม่กับ JS จะคาดหวังความจริงตั้งแต่ทำ.xในกล่องสตริงมันเป็นStringวัตถุ (และไม่ใช่ค่าดั้งเดิมของสตริง) และการเปรียบเทียบจะอยู่ระหว่างวัตถุและสตริง - นี่เป็นสิ่งที่ดีมาก บอบบางและเป็นหลุมพราง - สถิตยศาสตร์หลีกเลี่ยงปัญหาเหล่านี้วิธีการคงที่ง่ายและใช้งานง่ายขึ้น
Benjamin Gruenbaum

2
@ humble.rumble สำหรับการเปรียบเทียบโหนด DOM, มีอยู่แล้ววิธีการดังกล่าวเห็นisEqualNode ตัวอย่าง:document.createElement('div').isEqualNode(document.createElement('div')) === true
Rob W

2
2017 อัปเดต: Object.is () ได้รับการสนับสนุนอย่างกว้างขวางในเบราว์เซอร์หลักทั้งหมด
สเตอร์ลิงบอร์น

56

Object.isใช้ข้อกำหนดของอัลกอริทึม SameValueขณะที่===การนำมาใช้ประโยชน์อย่างเข้มงวดเท่าเทียมกันอัลกอริทึม หมายเหตุเกี่ยวกับอัลกอริธึม Strict Equality เรียกความแตกต่าง:

อัลกอริทึมนี้แตกต่างจากอัลกอริทึม SameValue ... ในการรักษาเลขศูนย์และ NaN

โปรดทราบว่า:

  • NaN === NaNเป็นเท็จ แต่Object.is(NaN, NaN)เป็นความจริง
  • +0 === -0เป็นจริง แต่Object.is(+0, -0)เป็นเท็จ
  • -0 === +0เป็นจริง แต่Object.is(-0, +0)เป็นเท็จ

JavaScript มี"ความเท่าเทียมกัน" อย่างน้อยสี่ชนิด:

  • "Loose" ( ==) ซึ่งตัวถูกดำเนินการจะถูกบังคับให้พยายามจับคู่ มีการระบุกฎไว้อย่างชัดเจนแต่ไม่ชัดเจน ( "" == 0is true; "true" == trueis false, ... )
  • "Strict" ( ===) ซึ่ง operand ของประเภทที่แตกต่างกันจะไม่ถูกบังคับ (และจะไม่เท่ากัน) แต่ดูหมายเหตุด้านบนเกี่ยวกับNaNศูนย์บวกและลบ
  • SameValue - ตามที่ระบุไว้ข้างต้น (ใช้งานโดยObject.is)
  • SameValueZero - like SameValueยกเว้น+0และ-0เหมือนกันแทนที่จะแตกต่างกัน (ใช้โดยMapสำหรับคีย์และโดยArray.prototype.includes)

นอกจากนี้ยังมีการเทียบเท่าวัตถุซึ่งไม่ได้จัดทำโดยภาษาหรือรันไทม์ของตัวเอง แต่มักจะแสดงเป็น: วัตถุที่มีต้นแบบเดียวกันคุณสมบัติเดียวกันและค่าคุณสมบัติของพวกเขาจะเหมือนกัน (ตามคำนิยามที่เหมาะสมของ "เดียวกัน" )


อัลกอริทึม SameValue :

  • หาก Type (x) แตกต่างจาก Type (y) ให้ส่งคืน false
  • หาก Type (x) คือ Number แสดงว่า
    • ถ้า x คือ NaN และ y คือ NaN ให้ส่งคืนจริง
    • หาก x คือ +0 และ y คือ -0 ให้ส่งคืน false
    • หาก x คือ -0 และ y คือ +0 ให้คืนค่า false
    • ถ้า x เป็นค่า Number เดียวกับ y ให้ส่งคืนจริง
    • กลับเท็จ
  • ส่งคืน SameValueNonNumber (x, y)

... โดยที่SameValueNonNumberคือ:

  • ยืนยัน: Type (x) ไม่ใช่ Number
  • ยืนยัน: Type (x) เหมือนกับ Type (y)
  • ถ้า Type (x) ไม่ได้ถูกกำหนดให้ส่งคืนจริง
  • ถ้า Type (x) เป็น Null ให้ส่งคืนจริง
  • ถ้า Type (x) เป็น String ดังนั้น
    • ถ้า x และ y เป็นลำดับของหน่วยรหัสที่เหมือนกัน (ความยาวเท่ากันและหน่วยรหัสเดียวกันที่ดัชนีที่สอดคล้องกัน) ให้คืนค่าจริง มิฉะนั้นส่งคืน false
  • ถ้า Type (x) เป็นบูลีน
    • ถ้า x และ y ทั้งจริงหรือเท็จทั้งคู่คืนจริง มิฉะนั้นส่งคืน false
  • หาก Type (x) เป็น Symbol แล้ว
    • ถ้า x และ y เป็นทั้งค่า Symbol เดียวกันให้คืนค่าจริง มิฉะนั้นส่งคืน false
  • ส่งคืนจริงถ้า x และ y เป็นค่าวัตถุเดียวกัน มิฉะนั้นส่งคืน false

อัลกอริทึมที่เท่าเทียมกันอย่างเข้มงวด :

  1. หาก Type (x) แตกต่างจาก Type (y) ให้ส่งคืน false
  2. หาก Type (x) คือ Number แสดงว่า
    • ถ้า x คือ NaN ให้คืนค่า false
    • ถ้า y เป็น NaN ให้ส่งคืน false
    • ถ้า x เป็นค่า Number เดียวกับ y ให้ส่งคืนจริง
    • ถ้า x เป็น +0 และ y คือ -0 ให้ส่งคืนจริง
    • ถ้า x คือ -0 และ y คือ +0 ให้คืนค่าจริง
    • กลับเท็จ
  3. ส่งคืน 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;
}

ข้างต้นเป็นฟังก์ชั่น polyfill เพื่อแสดงวิธีการObject.isทำงานสำหรับทุกคนที่สนใจที่จะรู้ การอ้างอิงถึงYou-Don't-Know-JS


2

สรุป:

Object.is()ฟังก์ชั่นใช้เวลา 2 ค่าเป็นข้อโต้แย้งและผลตอบแทนจริงถ้า 2 ค่าให้เป็นที่แน่นอนเดียวกันมิฉะนั้นจะกลับเท็จ

ทำไมเราต้องการสิ่งนี้

คุณอาจคิดว่าเรามีการตรวจสอบความเท่าเทียมกันอย่างเข้มงวด (การตรวจสอบประเภท + ค่า) ในจาวาสคริปต์กับ===โอเปอเรเตอร์แล้วทำไมเราต้องใช้ฟังก์ชันนี้ ความเท่าเทียมที่เข้มงวดไม่เพียงพอในบางกรณีและมีดังต่อไปนี้:

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

Object.is() ช่วยเราโดยสามารถเปรียบเทียบค่าเหล่านี้เพื่อดูว่ามีลักษณะคล้ายคลึงกันหรือไม่สิ่งที่ผู้ดำเนินการความเท่าเทียมกันอย่างเข้มงวดไม่สามารถทำได้

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

โดยสรุปแล้วพวกมันคล้ายกัน แต่Object.isฉลาดกว่าและแม่นยำกว่า ...

ลองดูที่นี่ ...

+0 === -0 //true

แต่มันไม่ถูกต้องอย่างที่มันไม่สนใจ-และ+ก่อน ...

ตอนนี้เราใช้:

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

อย่างที่คุณเห็นนี่เป็นการเปรียบเทียบที่แม่นยำกว่า

นอกจากนี้ในกรณีของการNaNทำงานที่ถูกต้องมากขึ้นเช่นพิจารณาใด ๆNaNที่เหมือนกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.