เรามาก้าวออกจากโครงสร้างข้อมูลแต่ละรายการและพูดคุยเกี่ยวกับการวนซ้ำเหนือโครงสร้างข้อมูลเหล่านั้น
ในบทที่แล้ว เราเห็นวิธีการ map.keys()
, map.values()
, map.entries()
วิธีการเหล่านี้เป็นวิธีการทั่วไป มีข้อตกลงทั่วไปที่จะใช้กับโครงสร้างข้อมูล หากเราสร้างโครงสร้างข้อมูลของเราเอง เราก็ควรนำไปใช้เช่นกัน
พวกเขาได้รับการสนับสนุนสำหรับ:
Map
Set
Array
วัตถุธรรมดายังรองรับวิธีการที่คล้ายกัน แต่ไวยากรณ์แตกต่างออกไปเล็กน้อย
สำหรับวัตถุธรรมดา มีวิธีการดังต่อไปนี้:
Object.keys(obj) – ส่งคืนอาร์เรย์ของคีย์
Object.values(obj) – ส่งคืนอาร์เรย์ของค่า
Object.entries(obj) – ส่งคืนอาร์เรย์ของคู่ [key, value]
โปรดทราบความแตกต่าง (เมื่อเทียบกับตัวอย่างแผนที่):
แผนที่ | วัตถุ | |
---|---|---|
ไวยากรณ์การโทร | map.keys() | Object.keys(obj) แต่ไม่ใช่ obj.keys() |
การส่งคืน | ทำซ้ำได้ | อาร์เรย์ "ของจริง" |
ข้อแตกต่างแรกคือเราต้องเรียก Object.keys(obj)
ไม่ใช่ obj.keys()
ทำไมเป็นเช่นนั้น? เหตุผลหลักคือความยืดหยุ่น โปรดจำไว้ว่า วัตถุเป็นฐานของโครงสร้างที่ซับซ้อนทั้งหมดใน JavaScript ดังนั้นเราอาจมี object ที่เป็น data
ของเราเองซึ่งใช้เมธอด data.values()
ของมันเอง และเรายังสามารถเรียก Object.values(data)
ได้
ข้อแตกต่างประการที่สองคือเมธอด Object.*
ส่งคืนอ็อบเจ็กต์อาร์เรย์ "ของจริง" ไม่ใช่แค่แบบวนซ้ำได้ นั่นเป็นเพราะเหตุผลทางประวัติศาสตร์เป็นหลัก
ตัวอย่างเช่น:
ให้ผู้ใช้ = { ชื่อ: "จอห์น" อายุ: 30 -
Object.keys(user) = ["name", "age"]
Object.values(user) = ["John", 30]
Object.entries(user) = [ ["name","John"], ["age",30] ]
นี่คือตัวอย่างของการใช้ Object.values
เพื่อวนซ้ำค่าคุณสมบัติ:
ให้ผู้ใช้ = { ชื่อ: "จอห์น" อายุ: 30 - // วนซ้ำค่า สำหรับ (ให้ค่าของ Object.values (ผู้ใช้)) { การแจ้งเตือน (ค่า); // จอห์น แล้ว 30 -
Object.keys/values/entries ละเว้นคุณสมบัติเชิงสัญลักษณ์
เช่นเดียวกับการวนซ้ำ for..in
วิธีการเหล่านี้จะละเว้นคุณสมบัติที่ใช้ Symbol(...)
เป็นคีย์
ปกติแล้วจะสะดวก แต่ถ้าเราต้องการคีย์สัญลักษณ์ด้วย ก็มีวิธี Object.getOwnPropertySymbols แยกกันที่ส่งคืนอาร์เรย์ของคีย์สัญลักษณ์เท่านั้น นอกจากนี้ยังมีเมธอด Reflect.ownKeys(obj) ที่ส่งคืนคีย์ ทั้งหมด
ออบเจ็กต์ขาดวิธีการมากมายสำหรับอาร์เรย์ เช่น map
filter
และอื่นๆ
หากเราต้องการนำไปใช้ เราสามารถใช้ Object.entries
ตามด้วย Object.fromEntries
:
ใช้ Object.entries(obj)
เพื่อรับอาร์เรย์ของคู่คีย์/ค่าจาก obj
ใช้วิธีการอาร์เรย์กับอาร์เรย์นั้น เช่น map
เพื่อแปลงคู่คีย์/ค่าเหล่านี้
ใช้ Object.fromEntries(array)
บนอาร์เรย์ผลลัพธ์เพื่อเปลี่ยนกลับเป็นวัตถุ
ตัวอย่างเช่น เรามีออบเจ็กต์ที่มีราคา และต้องการเพิ่มเป็นสองเท่า:
ให้ราคา = { กล้วย: 1, สีส้ม: 2, เนื้อ: 4, - ให้ doublePrices = Object.fromEntries( // แปลงราคาเป็นอาร์เรย์ แมปคู่คีย์/ค่าแต่ละคู่ให้เป็นอีกคู่หนึ่ง // จากนั้น fromEntries จะส่งคืนอ็อบเจ็กต์ Object.entries(ราคา).map(entry => [รายการ[0], รายการ[1] * 2]) - การแจ้งเตือน (doublePrices.meat); // 8
อาจดูยากตั้งแต่แรกเห็น แต่จะเข้าใจได้ง่ายหลังจากใช้งานครั้งหรือสองครั้ง เราสามารถสร้างห่วงโซ่แห่งการเปลี่ยนแปลงอันทรงพลังได้ด้วยวิธีนี้
ความสำคัญ: 5
มีวัตถุ salaries
ที่มีจำนวนเงินเดือนโดยพลการ
เขียนฟังก์ชัน sumSalaries(salaries)
ที่ส่งคืนผลรวมของเงินเดือนทั้งหมดโดยใช้ Object.values
และ for..of
loop
หาก salaries
ว่างเปล่า ผลลัพธ์จะต้องเป็น 0
ตัวอย่างเช่น:
ให้เงินเดือน = { "จอห์น": 100, "พีท": 300, "แมรี่": 250 - alert( เงินเดือนรวม(เงินเดือน) ); // 650
เปิดแซนด์บ็อกซ์พร้อมการทดสอบ
ฟังก์ชั่น sumSalaries(เงินเดือน) { ให้ผลรวม = 0; สำหรับ (ให้เงินเดือนของ Object.values(salaries)) { ผลรวม += เงินเดือน; - จำนวนเงินที่ส่งคืน; // 650 - ให้เงินเดือน = { "จอห์น": 100, "พีท": 300, "แมรี่": 250 - alert( เงินเดือนรวม(เงินเดือน) ); // 650
หรืออีกทางเลือกหนึ่ง เรายังสามารถรับผลรวมโดยใช้ Object.values
และ reduce
:
// ลดการวนซ้ำของเงินเดือน //บวกพวกมันเข้าไป // และส่งคืนผลลัพธ์ ฟังก์ชั่น sumSalaries(เงินเดือน) { return Object.values(salaries).reduce((a, b) => a + b, 0) // 650 -
เปิดโซลูชันพร้อมการทดสอบในแซนด์บ็อกซ์
ความสำคัญ: 5
เขียนฟังก์ชัน count(obj)
ที่ส่งคืนจำนวนคุณสมบัติในวัตถุ:
ให้ผู้ใช้ = { ชื่อ: 'จอห์น' อายุ: 30 - การแจ้งเตือน ( นับ (ผู้ใช้) ); // 2
พยายามทำให้โค้ดสั้นที่สุด
PS ละเว้นคุณสมบัติเชิงสัญลักษณ์ นับเฉพาะคุณสมบัติ "ปกติ" เท่านั้น
เปิดแซนด์บ็อกซ์พร้อมการทดสอบ
ฟังก์ชั่นนับ (obj) { กลับ Object.keys (obj). ความยาว; -
เปิดโซลูชันพร้อมการทดสอบในแซนด์บ็อกซ์