นอกเหนือจากการอ่านที่ดีขึ้นจะมีประโยชน์ใด ๆ ที่includes
มากกว่าindexOf
? พวกเขาดูเหมือนกับฉัน
อะไรคือความแตกต่างระหว่างสิ่งนี้
var x = [1,2,3].indexOf(1) > -1; //true
และนี่?
var y = [1,2,3].includes(1); //true
นอกเหนือจากการอ่านที่ดีขึ้นจะมีประโยชน์ใด ๆ ที่includes
มากกว่าindexOf
? พวกเขาดูเหมือนกับฉัน
อะไรคือความแตกต่างระหว่างสิ่งนี้
var x = [1,2,3].indexOf(1) > -1; //true
และนี่?
var y = [1,2,3].includes(1); //true
includes
ไม่ใช่ส่วนหนึ่งของ ES6 / ES2015 เป็นข้อเสนอสำหรับ ECMAScript เวอร์ชันถัดไปและจะเพิ่มในปีนี้
includes
ไม่รองรับใน IE เลย
คำตอบ:
tl; dr: NaN
ได้รับการปฏิบัติที่แตกต่างกัน:
[NaN].indexOf(NaN) > -1
คือ false
[NaN].includes(NaN)
คือ true
จากข้อเสนอ :
แรงจูงใจ
เมื่อใช้อาร์เรย์ ECMAScript โดยทั่วไปต้องการตรวจสอบว่าอาร์เรย์มีองค์ประกอบหรือไม่ รูปแบบที่แพร่หลายสำหรับสิ่งนี้คือ
if (arr.indexOf(el) !== -1) { ... }
มีความเป็นไปได้อื่น ๆ อีกมากมายเช่นหรือแม้กระทั่ง
arr.indexOf(el) >= 0
~arr.indexOf(el)
รูปแบบเหล่านี้แสดงปัญหาสองประการ:
- พวกเขาไม่ "พูดในสิ่งที่คุณหมายถึง": แทนที่จะถามว่าอาร์เรย์มีองค์ประกอบหรือไม่คุณถามว่าดัชนีของการเกิดขึ้นครั้งแรกขององค์ประกอบนั้นในอาร์เรย์คืออะไรจากนั้นจึงเปรียบเทียบหรือบิดบิตเพื่อพิจารณา คำตอบสำหรับคำถามที่แท้จริงของคุณ
- พวกเขาล้มเหลว
NaN
เนื่องจากindexOf
ใช้การเปรียบเทียบความเท่าเทียมกันอย่างเข้มงวดและด้วยเหตุ[NaN].indexOf(NaN) === -1
นี้โซลูชันที่เสนอ
เราขอเสนอวิธีการเพิ่มเติม
Array.prototype.includes
เพื่อให้รูปแบบข้างต้นสามารถเขียนใหม่ได้if (arr.includes(el)) { ... }
สิ่งนี้มีความหมายเกือบจะเหมือนกับข้างต้นยกเว้นว่าจะใช้อัลกอริธึมการเปรียบเทียบ SameValueZero แทนการเปรียบเทียบความเสมอภาคอย่างเข้มงวดจึงทำให้
[NaN].includes(NaN)
เป็นจริงดังนั้นข้อเสนอนี้จะช่วยแก้ปัญหาทั้งสองอย่างที่พบในโค้ดที่มีอยู่
นอกจากนี้เรายังเพิ่ม
fromIndex
พารามิเตอร์ที่คล้ายกับArray.prototype.indexOf
และString.prototype.includes
เพื่อความสอดคล้อง
ข้อมูลเพิ่มเติม:
undefined
โดยและไม่ได้รับการพิจารณาโดย.includes()
.indexOf()
หากคุณสงสัยเกี่ยวกับประสิทธิภาพในขณะนี้ indexOf จะเร็วกว่า แต่การทดสอบJSperfนี้มักจะแสดงให้เห็นว่าเวลาผ่านไปมากขึ้นincludes()
จะเร็วกว่าindexOf
(ฉันเดาว่ามันจะได้รับการปรับให้เหมาะสมต่อไป)
IMHO ฉันชอบเขียนif (arr.includes(el)) {}
เนื่องจากมีความชัดเจนและสามารถบำรุงรักษาได้มากกว่าif (arr.indexOf(el) !== -1) {}
.indexOf()
และ.includes()
วิธีการสามารถใช้เพื่อค้นหาองค์ประกอบในอาร์เรย์หรือเพื่อค้นหาอักขระ / สตริงย่อยในสตริงที่กำหนด
( ลิงก์ไปยังข้อกำหนด ECMAScript)
indexOf
ใช้การเปรียบเทียบความเท่าเทียมกันอย่างเข้มงวดในขณะที่includes
ใช้อัลกอริทึมSameValueZero ด้วยเหตุนี้ความแตกต่างสองประการต่อไปนี้จึงเกิดขึ้น
ในฐานะที่เป็นแหลมออกโดยเฟลิกซ์แพรวNaN
พฤติกรรมที่แตกต่างกันในกรณีของ
let arr = [NaN];
arr.indexOf(NaN); // returns -1; meaning NaN is not present
arr.includes(NaN); // returns true
undefined
พฤติกรรมยังแตกต่างกันในกรณีของlet arr = [ , , ];
arr.indexOf(undefined); // returns -1; meaning undefined is not present
arr.includes(undefined); // returns true
( ลิงก์ไปยังข้อกำหนด ECMAScript)
indexOf
จะถือว่า RegExp เป็นสตริงและจะส่งคืนดัชนีของสตริงหากพบ อย่างไรก็ตามหากคุณส่ง RegExp ไปincludes
ก็จะทำให้เกิดข้อยกเว้นlet str = "javascript";
str.indexOf(/\w/); // returns -1 even though the elements match the regex because /\w/ is treated as string
str.includes(/\w/); // throws TypeError: First argument to String.prototype.includes must not be a regular expression
ดังที่538ROMEOชี้ให้เห็นincludes
อาจช้าลงเล็กน้อย (เล็กมาก) เล็กน้อย (เนื่องจากจำเป็นต้องตรวจสอบ regex เป็นอาร์กิวเมนต์แรก) มากกว่าindexOf
แต่ในความเป็นจริงสิ่งนี้ไม่ได้สร้างความแตกต่างมากนักและไม่มีความสำคัญ
String.prototype.includes()
ได้รับการแนะนำใน ECMAScript 2015 ในขณะที่Array.prototype.includes()
เปิดตัวใน ECMAScript 2016 สำหรับการสนับสนุนเบราว์เซอร์ให้ใช้อย่างชาญฉลาด
String.prototype.indexOf()
และArray.prototype.indexOf()
มีอยู่ใน ECMAScript รุ่น ES5 และด้วยเหตุนี้จึงสนับสนุนโดยเบราว์เซอร์ทั้งหมด
indexOf
ให้true
หลังจากตั้งค่าอย่างชัดเจนundefined
ในอาร์เรย์: let arr=[undefined];
หรือlet arr=[];arr[0]=undefined;
ตอนนี้arr.indexOf(undefined) === 0
undefined
เหตุผลก็คือ.includes
ถือว่าองค์ประกอบที่ขาดหายไปในundefined
ขณะที่.indexOf()
ไม่สนใจองค์ประกอบเหล่านั้น นอกจากนี้คุณยังสามารถ“สร้าง” arr[number beyond length] = whatever
องค์ประกอบที่ขาดหายไปด้วย
.includes()
กินเฉพาะสาย ในความเป็นจริงทั้งสองวิธีบังคับให้สตริงใด ๆ ดีที่สุดเท่าที่จะทำได้ Regex ได้รับการยกเว้นเฉพาะเป็นอาร์กิวเมนต์.includes()
ที่จะอนุญาตให้มีการเพิ่มเติมในอนาคตให้ได้มาตรฐานตามที่ร่างปัจจุบัน
ตามแนวคิดคุณควรใช้ indexOf เมื่อคุณต้องการใช้ตำแหน่ง indexOf เพียงแค่ให้คุณแยกค่าหรือดำเนินการกับอาร์เรย์เช่นใช้ slice, shift หรือ split หลังจากที่คุณได้ตำแหน่งขององค์ประกอบ ในทางกลับกัน Use Array.inc รวมเฉพาะเพื่อให้ทราบว่าค่านั้นอยู่ในอาร์เรย์หรือไม่และไม่ใช่ตำแหน่งเพราะคุณไม่สนใจมัน
indexOf()
และincludes()
สามารถใช้ทั้งสองอย่างเพื่อค้นหาองค์ประกอบในอาร์เรย์อย่างไรก็ตามแต่ละฟังก์ชันจะให้ค่าตอบแทนที่แตกต่างกัน
indexOf
ส่งคืนตัวเลข ( -1
หากองค์ประกอบไม่มีอยู่ในอาร์เรย์หรือตำแหน่งอาร์เรย์หากมีองค์ประกอบอยู่)
includes()
ส่งคืนค่าบูลีน ( true
หรือfalse
)
includes
มีการรองรับเบราว์เซอร์ที่แย่กว่ามาก