ecmascript 6 - ฉันจะรวมวัตถุ JavaScript สองตัวเข้าด้วยกันใน ES6+ ได้อย่างไร?
ฉันเบื่อและเหนื่อยกับการต้องเขียนโค้ดแบบนี้ตลอดเวลา:
function shallowExtend(obj1,obj2){
var key;
for ( key in obj2 ) {
if ( obj2.hasOwnProperty(key) === false ) continue;
obj1[key] = obj2[key]
}
}
หรือถ้าฉันไม่ต้องการเขียนโค้ดเอง ให้ใช้ไลบรารีที่มีฟังก์ชันนั้นอยู่แล้ว แน่นอนว่า ES6+ จะเข้ามาช่วยในเรื่องนี้และจะให้สิ่งที่คล้ายกับ Object.prototype.extend(obj2...) หรือ Object.extend(obj1,obj2...)
แล้ว ES6+ ให้ฟังก์ชันดังกล่าวหรือไม่? ถ้ายังไม่มีอยู่ ฟังก์ชันดังกล่าวถูกวางแผนไว้หรือไม่? ถ้าไม่ได้วางแผนไว้ ทำไมถึงไม่ได้วางแผน?
คำตอบ #1
คุณจะสามารถทำการรวม/ขยาย/กำหนดค่าระดับตื้นใน ES6 โดยใช้ Object.assign:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
ไวยากรณ์:
Object.assign(target, sources);
ซึ่ง ...sources แทนวัตถุแหล่งที่มา
ตัวอย่าง:
var obj1 = {name: 'Daisy', age: 30};
var obj2 = {name: 'Casey'};
Object.assign(obj1, obj2);
console.log(obj1.name === 'Casey' && obj1.age === 30);
// true
คำตอบ #2
คุณสามารถใช้ไวยากรณ์กระจายวัตถุสำหรับสิ่งนี้ได้:
const merged = {...obj1, ...obj2}
สำหรับอาเรย์ ตัวดำเนินการกระจาย (spread operator) เป็นส่วนหนึ่งของ ES6 (ES2015) อยู่แล้ว แต่สำหรับอ็อบเจ็กต์มันถูกเพิ่มเข้าไปในข้อกำหนดของภาษาใน ES9 (ES2018) ข้อเสนอของมันถูกเปิดใช้งานโดยค่าเริ่มต้นในเครื่องมือต่าง ๆ เช่น Babel มานานก่อนหน้านั้น
คำตอบ #3
ฉันรู้ว่านี่เป็นปัญหาที่ค่อนข้างเก่าอยู่เล็กน้อย แต่วิธีแก้ปัญหาที่ง่ายที่สุดใน ES2015/ES6 นั้นจริง ๆ แล้วค่อนข้างง่าย โดยใช้ Object.assign()
หวังว่านี่จะช่วยได้ สิ่งนี้ยังทำการรวม ลึก ด้วย:
/**
* Simple is object check.
* @param item
* @returns {boolean}
*/
export function isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item) && item !== null);
}
/**
* Deep merge two objects.
* @param target
* @param source
*/
export function mergeDeep(target, source) {
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return target;
}
ตัวอย่างการใช้งาน:
mergeDeep(this, { a: { b: { c: 123 } } });
// or
const merged = mergeDeep({a: 1}, { b : { c: { d: { e: 12345}}}});
console.dir(merged); // { a: 1, b: { c: { d: [Object] } } }
