การทำลายล้าง ES6
ไวยากรณ์การทำลายล้างช่วยให้สามารถจัดใหม่และรวบรวมวัตถุใหม่ด้วยพารามิเตอร์ฟังก์ชันหรือตัวแปร
ข้อ จำกัด คือรายการของคีย์ถูกกำหนดไว้ล่วงหน้าซึ่งไม่สามารถแสดงรายการเป็นสตริงได้ตามคำถามที่กล่าวถึง Destructuring foo_barกลายเป็นความซับซ้อนมากขึ้นหากที่สำคัญคือไม่ใช่ตัวเลขเช่น
ข้อเสียคือต้องทำซ้ำรายการของคีย์ผลลัพธ์นี้ในรหัส verbose ในกรณีที่รายการมีความยาว เนื่องจากการทำลายโครงสร้างซ้ำไวยากรณ์ของตัวอักษรวัตถุในกรณีนี้รายการสามารถคัดลอกและวางตามที่เป็นอยู่
ข้อเสียคือโซลูชันของนักแสดงที่เป็นธรรมชาติของ ES6
IIFE
let subset = (({ foo, bar }) => ({ foo, bar }))(obj); // dupe ({ foo, bar })
ตัวแปรชั่วคราว
let { foo, bar } = obj;
let subset = { foo, bar }; // dupe { foo, bar }
รายการของสตริง
รายการคีย์ที่เลือกโดยพลการประกอบด้วยสตริงตามที่คำถามต้องการ สิ่งนี้อนุญาตให้ไม่กำหนดค่าล่วงหน้าและใช้ตัวแปรที่มีชื่อคีย์เช่นpick(obj, 'foo', someKey, ...moreKeys)พวกเขาและใช้ตัวแปรที่มีชื่อที่สำคัญเช่น
สายการบินหนึ่งจะสั้นลงเมื่อใช้รุ่น JS
ES5
var subset = Object.keys(obj)
.filter(function (key) {
return ['foo', 'bar'].indexOf(key) >= 0;
})
.reduce(function (obj2, key) {
obj2[key] = obj[key];
return obj2;
}, {});
ES6
let subset = Object.keys(obj)
.filter(key => ['foo', 'bar'].indexOf(key) >= 0)
.reduce((obj2, key) => Object.assign(obj2, { [key]: obj[key] }), {});
หรือด้วยเครื่องหมายจุลภาค:
let subset = Object.keys(obj)
.filter(key => ['foo', 'bar'].indexOf(key) >= 0)
.reduce((obj2, key) => (obj2[key] = obj[key], obj2), {});
ES2019
ECMAScript 2017 มีObject.entriesและArray.prototype.includesECMAScript 2019 มีObject.fromEntriesพวกเขาสามารถ polyfilled เมื่อจำเป็นและทำให้งานง่ายขึ้น:
let subset = Object.fromEntries(
Object.entries(obj)
.filter(([key]) => ['foo', 'bar'].includes(key))
)
หนึ่งซับสามารถเขียนใหม่เป็นฟังก์ชันตัวช่วยคล้ายกับLodashpickหรือomitตำแหน่งของคีย์ถูกส่งผ่านอาร์กิวเมนต์:
let pick = (obj, ...keys) => Object.fromEntries(
Object.entries(obj)
.filter(([key]) => keys.includes(key))
);
let subset = pick({ foo: 1, qux: 2 }, 'foo', 'bar'); // { foo: 1 }
หมายเหตุเกี่ยวกับกุญแจที่หายไป
ความแตกต่างที่สำคัญระหว่างpickฟังก์ชั่นการทำลายล้างและการทำงานเหมือน Lodash ทั่วไปคือการทำลายล้างนั้นรวมถึงปุ่มเลือกที่ไม่มีอยู่จริงพร้อมundefinedค่าในชุดย่อย:
(({ foo, bar }) => ({ foo, bar }))({ foo: 1 }) // { foo: 1, bar: undefined }
พฤติกรรมนี้อาจเป็นที่ต้องการหรือไม่ก็ได้ ไม่สามารถเปลี่ยนแปลงได้สำหรับการทำลายไวยากรณ์
ในขณะที่pickสามารถเปลี่ยนเป็นรวมคีย์ที่หายไปได้โดยทำซ้ำรายการของคีย์ที่เลือกแทน:
let inclusivePick = (obj, ...keys) => Object.fromEntries(
keys.map(key => [key, obj[key]])
);
let subset = inclusivePick({ foo: 1, qux: 2 }, 'foo', 'bar'); // { foo: 1, bar: undefined }