เหตุใดวัตถุจึงไม่สามารถทำซ้ำได้ตามค่าเริ่มต้น
ฉันเห็นคำถามตลอดเวลาที่เกี่ยวข้องกับการวนซ้ำออบเจ็กต์วิธีแก้ปัญหาทั่วไปคือการวนซ้ำคุณสมบัติของอ็อบเจ็กต์และเข้าถึงค่าภายในอ็อบเจ็กต์ด้วยวิธีนั้น สิ่งนี้ดูธรรมดามากจนทำให้ฉันสงสัยว่าทำไมวัตถุต่างๆถึงไม่สามารถทำซ้ำได้
คำสั่งเช่น ES6 for...of
น่าใช้สำหรับวัตถุโดยค่าเริ่มต้น เนื่องจากคุณลักษณะเหล่านี้มีให้เฉพาะสำหรับ "อ็อบเจ็กต์ที่ทำซ้ำได้" แบบพิเศษซึ่งไม่รวมอ{}
อบเจ็กต์เราจึงต้องผ่านห่วงเพื่อให้สามารถใช้งานกับวัตถุที่เราต้องการใช้
คำสั่ง for ... of สร้าง loop วนซ้ำบนวัตถุที่ทำซ้ำได้ (รวมถึง Array, Map, Set, วัตถุอาร์กิวเมนต์และอื่น ๆ ) ...
ตัวอย่างเช่นการใช้ฟังก์ชันเครื่องกำเนิด ES6 :
var example = {a: {e: 'one', f: 'two'}, b: {g: 'three'}, c: {h: 'four', i: 'five'}};
function* entries(obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
}
for (let [key, value] of entries(example)) {
console.log(key);
console.log(value);
for (let [key, value] of entries(value)) {
console.log(key);
console.log(value);
}
}
ข้างต้นบันทึกข้อมูลอย่างถูกต้องตามลำดับที่ฉันคาดหวังเมื่อฉันเรียกใช้โค้ดใน Firefox (ซึ่งรองรับES6 ):
โดยค่าเริ่มต้น{}
วัตถุจะไม่สามารถทำซ้ำได้ แต่ทำไม? ข้อเสียจะมีมากกว่าประโยชน์ที่เป็นไปได้ของวัตถุที่สามารถทำซ้ำได้หรือไม่? อะไรคือปัญหาที่เกี่ยวข้องกับสิ่งนี้?
นอกจากนี้เนื่องจาก{}
วัตถุที่มีความแตกต่างจาก "อาร์เรย์เหมือน" คอลเลกชันและ "วัตถุ iterable" เช่นNodeList
, HtmlCollection
และarguments
พวกเขาจะไม่สามารถแปลงเป็นอาร์เรย์
ตัวอย่างเช่น:
var argumentsArray = Array.prototype.slice.call(arguments);
หรือใช้กับเมธอด Array:
Array.prototype.forEach.call(nodeList, function (element) {})
.
นอกเหนือจากคำถามที่ฉันมีข้างต้นฉันชอบที่จะเห็นตัวอย่างการทำงานเกี่ยวกับวิธีสร้าง{}
วัตถุให้เป็นรูปแบบซ้ำโดยเฉพาะจากผู้ที่กล่าวถึงไฟล์[Symbol.iterator]
. นี้จะช่วยให้ใหม่เหล่านี้{}
"วัตถุ iterable" for...of
งบการใช้งานเช่น นอกจากนี้ฉันสงสัยว่าการทำให้ออบเจ็กต์ทำซ้ำได้ทำให้สามารถแปลงเป็น Arrays ได้หรือไม่
ฉันลองใช้รหัสด้านล่าง แต่ได้รับไฟล์TypeError: can't convert undefined to object
.
var example = {a: {e: 'one', f: 'two'}, b: {g: 'three'}, c: {h: 'four', i: 'five'}};
// I want to be able to use "for...of" for the "example" object.
// I also want to be able to convert the "example" object into an Array.
example[Symbol.iterator] = function* (obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
};
for (let [key, value] of example) { console.log(value); } // error
console.log([...example]); // error
Symbol.iterator
คุณสมบัติเป็นสิ่งที่ทำซ้ำได้ ดังนั้นคุณต้องใช้คุณสมบัตินั้น คำอธิบายที่เป็นไปได้อย่างหนึ่งสำหรับสาเหตุที่วัตถุไม่สามารถทำซ้ำได้อาจเป็นได้ว่าสิ่งนี้บ่งบอกถึงทุกสิ่งที่ทำซ้ำได้เนื่องจากทุกอย่างเป็นวัตถุ (ยกเว้นวัตถุดั้งเดิมแน่นอน) อย่างไรก็ตามการวนซ้ำบนฟังก์ชันหรืออ็อบเจกต์นิพจน์ทั่วไปหมายความว่าอย่างไร