นอกเหนือจากการอ่านที่ดีขึ้นจะมีประโยชน์ใด ๆ ที่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มีการรองรับเบราว์เซอร์ที่แย่กว่ามาก