เช่นถ้าฉันมีวัตถุสองชิ้น:
var foo = {
x: "bar",
y: "baz"
}
และ
var oof = {}
และฉันต้องการถ่ายโอนค่า x และ y จาก foo ไปยัง oof มีวิธีการทำเช่นนั้นโดยใช้ไวยากรณ์ destructuring es6 หรือไม่?
อาจจะชอบ:
oof{x,y} = foo
Object.assign
เช่นถ้าฉันมีวัตถุสองชิ้น:
var foo = {
x: "bar",
y: "baz"
}
และ
var oof = {}
และฉันต้องการถ่ายโอนค่า x และ y จาก foo ไปยัง oof มีวิธีการทำเช่นนั้นโดยใช้ไวยากรณ์ destructuring es6 หรือไม่?
อาจจะชอบ:
oof{x,y} = foo
Object.assign
คำตอบ:
ในขณะที่น่าเกลียดและซ้ำ ๆ คุณสามารถทำได้
({x: oof.x, y: oof.y} = foo);
ซึ่งจะอ่านค่าสองค่าของfooวัตถุและเขียนไปยังตำแหน่งที่เกี่ยวข้องบนoofวัตถุ
โดยส่วนตัวแล้วฉันยังอยากอ่าน
oof.x = foo.x;
oof.y = foo.y;
หรือ
['x', 'y'].forEach(prop => oof[prop] = foo[prop]);
แม้
var oof = {};แล้ว
({x: oof.x, y: oof.y} = foo)? ฉันคิดว่าคุณได้ใส่เป็นพิเศษฉในOOF
ไม่การทำลายไม่สนับสนุนการแสดงออกของสมาชิกในชวเลข แต่เป็นเพียงชื่อทรัพย์สินธรรมดาในเวลาปัจจุบัน มีการพูดคุยเกี่ยวกับเรื่องนี้ใน esdiscuss แต่ไม่มีข้อเสนอใด ๆ ที่จะทำให้มันกลายเป็น ES6
คุณอาจสามารถใช้งานได้Object.assign- หากคุณไม่ต้องการคุณสมบัติของตัวเองทั้งหมดคุณยังสามารถทำได้
var foo = …,
oof = {};
{
let {x, y} = foo;
Object.assign(oof, {x, y})
}
--harmony_destructuringเปิดใช้งาน ฉันเห็น "SyntaxError: โทเค็นที่ไม่คาดคิด"
{oof.x, oof.y} = fooไม่ฉันไม่คิดว่ามันเปลี่ยนไปผมคิดว่าผมได้พูดคุยเกี่ยวกับ หรือบางทีฉันอาจจะพลาดมันจริงๆ
IMO นี่เป็นวิธีที่ง่ายที่สุดในการบรรลุสิ่งที่คุณต้องการ:
let { prop1, prop2, prop3 } = someObject;
let data = { prop1, prop2, prop3 };
// data === { prop1: someObject.prop1, ... }
โดยพื้นฐานแล้วให้โครงสร้างเป็นตัวแปรแล้วใช้ initializer ชวเลขเพื่อสร้างวัตถุใหม่ ไม่ต้องการObject.assign
ฉันคิดว่านี่เป็นวิธีที่อ่านได้มากที่สุดอย่างไรก็ตาม คุณสามารถเลือกอุปกรณ์ประกอบฉากที่แน่นอนจากsomeObjectที่คุณต้องการ หากคุณมีวัตถุที่มีอยู่คุณเพียงต้องการรวมอุปกรณ์ประกอบฉากเข้ามาทำสิ่งนี้:
let { prop1, prop2, prop3 } = someObject;
let data = Object.assign(otherObject, { prop1, prop2, prop3 });
// Makes a new copy, or...
Object.assign(otherObject, { prop1, prop2, prop3 });
// Merges into otherObject
อีกวิธีหนึ่งที่สะอาดกว่าวิธีเขียนคือ:
let { prop1, prop2, prop3 } = someObject;
let newObject = { prop1, prop2, prop3 };
// Merges your selected props into otherObject
Object.assign(otherObject, newObject);
ฉันใช้สิ่งนี้เพื่อPOSTขอสิ่งต่างๆมากมายซึ่งฉันต้องการข้อมูลที่ไม่ต่อเนื่องเพียงไม่กี่ชิ้น แต่ฉันเห็นด้วยควรมีหนึ่งซับในการทำเช่นนี้
แก้ไข: PS - ฉันเพิ่งเรียนรู้ว่าคุณสามารถใช้การทำลายล้างขั้นสูงในขั้นตอนแรกเพื่อดึงค่าที่ซ้อนกันออกจากวัตถุที่ซับซ้อน! เช่น ...
let { prop1,
prop2: { somethingDeeper },
prop3: {
nested1: {
nested2
}
} = someObject;
let data = { prop1, somethingDeeper, nested2 };
นอกจากนี้คุณสามารถใช้ตัวดำเนินการสเปรดแทน Object.assign เมื่อสร้างวัตถุใหม่:
const { prop1, prop2, prop3 } = someObject;
let finalObject = {...otherObject, prop1, prop2, prop3 };
หรือ...
const { prop1, prop2, prop3 } = someObject;
const intermediateObject = { prop1, prop2, prop3 };
const finalObject = {...otherObject, ...intermediateObject };
นอกจากObject.assignนี้ยังมีไวยากรณ์การแพร่กระจายวัตถุซึ่งเป็นข้อเสนอขั้นที่ 2 สำหรับ ECMAScript
var foo = {
x: "bar",
y: "baz"
}
var oof = { z: "z" }
oof = {...oof, ...foo }
console.log(oof)
/* result
{
"x": "bar",
"y": "baz",
"z": "z"
}
*/
แต่ในการใช้คุณสมบัตินี้คุณต้องใช้stage-2หรือtransform-object-rest-spreadปลั๊กอินสำหรับ babel นี่คือตัวอย่างของ Babel ด้วยstage-2
หากคุณใช้BabelJSคุณสามารถเปิดใช้งานปลั๊กอินของฉันได้babel-plugin-transform-object-from-destructuring( ดูแพ็คเกจสำหรับการติดตั้งและการใช้งาน )
ฉันมีปัญหาเดียวกันที่อธิบายไว้ในหัวข้อนี้และสำหรับฉันมันเหนื่อยมากเมื่อคุณสร้างวัตถุจากนิพจน์การทำลายล้างโดยเฉพาะอย่างยิ่งเมื่อคุณต้องเปลี่ยนชื่อเพิ่มหรือลบคุณสมบัติ ด้วยปลั๊กอินนี้การบำรุงรักษาสถานการณ์ดังกล่าวทำให้คุณง่ายขึ้น
let myObject = {
test1: "stringTest1",
test2: "stringTest2",
test3: "stringTest3"
};
let { test1, test3 } = myObject,
myTest = { test1, test3 };
สามารถเขียนเป็น:
let myTest = { test1, test3 } = myObject;
let myArray = ["stringTest1", "stringTest2", "stringTest3"];
let [ test1, , test3 ] = myArray,
myTest = [ test1, test3 ];
สามารถเขียนเป็น:
let myTest = [ test1, , test3 ] = myArray;
let myTest = { test1, test3 } = myObject;ไม่ทำงาน
เป็นไปได้โดยสิ้นเชิง ไม่ได้อยู่ในแถลงการณ์เดียว
var foo = {
x: "bar",
y: "baz"
};
var oof = {};
({x: oof.x, y: oof.y} = foo); // {x: "bar", y: "baz"}
(โปรดจำไว้ว่าวงเล็บอยู่รอบ ๆ คำสั่ง) แต่โปรดจำไว้เสมอว่าการอ่านโค้ดมีความสำคัญมากกว่าการเขียนโค้ด :)
ที่มา: http://exploringjs.com/es6/ch_destructuring.html#sec_assignment-targets
คุณสามารถใช้การปรับโครงสร้างสำหรับสิ่งนี้:
const foo = {x:"a", y:"b"};
const {...oof} = foo; // {x:"a", y:"b"}
หรือผสานวัตถุทั้งสองถ้า oof มีค่า:
const foo = {x:"a", y:"b"};
let oof = {z:"c"}
oof = Object.assign({}, oof, foo)
oof = {...oof, ...foo}
คุณสามารถส่งคืนวัตถุที่ถูกทำลายได้ในฟังก์ชั่นลูกศรและใช้ Object.assign () เพื่อกำหนดให้กับตัวแปร
const foo = {
x: "bar",
y: "baz"
}
const oof = Object.assign({}, () => ({ x, y } = foo));
แห้ง
var a = {a1:1, a2: 2, a3: 3};
var b = {b1:1, b2: 2, b3: 3};
const newVar = (() => ({a1, a2, b1, b2})).bind({...a, ...b});
const val = newVar();
console.log({...val});
// print: Object { a1: 1, a2: 2, b1: 1, b2: 2 }
หรือ
console.log({...(() => ({a1, a2, b1, b2})).bind({...a, ...b})()});
คุณสามารถทำลายวัตถุที่กำหนดให้กับแอตทริบิวต์ของวัตถุอื่นโดยตรง
ตัวอย่างการทำงาน:
let user = {};
[user.name, user.username] = "Stack Overflow".split(' ');
document.write(`
1st attr: ${user.name} <br />
2nd attr: ${user.username}`);
คุณสามารถทำงานกับการทำลายโดยใช้ตัวแปรที่มีชื่อเดียวกันกับแอตทริบิวต์ของวัตถุที่คุณต้องการจับด้วยวิธีนี้คุณไม่จำเป็นต้องทำ:
let user = { name: 'Mike' }
let { name: name } = user;
ใช้วิธีนี้:
let user = { name: 'Mike' }
let { name } = user;
เช่นเดียวกับที่คุณสามารถกำหนดค่าใหม่ให้กับโครงสร้างวัตถุหากมีชื่อแอตทริบิวต์เดียวกัน
ดูตัวอย่างการทำงานนี้:
// The object to be destructed
let options = {
title: "Menu",
width: 100,
height: 200
};
// Destructing
let {width: w, height: h, title} = options;
// Feedback
document.write(title + "<br />"); // Menu
document.write(w + "<br />"); // 100
document.write(h); // 200
ใช้งานได้ใน chrome 53.0.2785.89
let foo = {
x: "bar",
y: "baz"
};
let oof = {x, y} = foo;
console.log(`oof: ${JSON.stringify(oof)});
//prints
oof: {
"x": "bar",
"y": "baz"
}
oofเพิ่งได้รับการอ้างอิงfooและข้ามการทำลายล้างทั้งหมด (อย่างน้อยก็ใน Chrome) oof === fooและlet oof = { x } = fooยังส่งคืน{ x, y }
ฉันมาด้วยวิธีนี้:
exports.pick = function pick(src, props, dest={}) {
return Object.keys(props).reduce((d,p) => {
if(typeof props[p] === 'string') {
d[props[p]] = src[p];
} else if(props[p]) {
d[p] = src[p];
}
return d;
},dest);
};
ซึ่งคุณสามารถใช้สิ่งนี้:
let cbEvents = util.pick(this.props.events, {onFocus:1,onBlur:1,onCheck:'onChange'});
let wrapEvents = util.pick(this.props.events, {onMouseEnter:1,onMouseLeave:1});
กล่าวคือคุณสามารถเลือกคุณสมบัติที่คุณต้องการและนำไปใส่ในวัตถุใหม่ ซึ่งแตกต่างจาก_.pickคุณยังสามารถเปลี่ยนชื่อพวกเขาในเวลาเดียวกัน
หากคุณต้องการคัดลอกอุปกรณ์ประกอบฉากไปยังวัตถุที่มีอยู่เพียงแค่ตั้งค่าdestหาเรื่อง
นี่เป็นการโกง แต่คุณสามารถทำสิ่งนี้ได้ ...
const originalObject = {
hello: 'nurse',
meaningOfLife: 42,
your: 'mom',
};
const partialObject = (({ hello, your }) => {
return { hello, your };
})(originalObject);
console.log(partialObject); // { hello: 'nurse', your: 'mom' }
ในทางปฏิบัติฉันคิดว่าคุณไม่ค่อยต้องการใช้สิ่งนั้น ต่อไปนี้ชัดเจนมาก ... แต่ไม่ค่อยสนุกเท่าไหร่
const partialObject = {
hello: originalObject.hello,
your: originalObject.your,
};
อีกเส้นทางที่แตกต่างอย่างสิ้นเชิงซึ่งรวมถึงการดัดแปลงต้นแบบ (ระวังตอนนี้ ... ):
if (!Object.prototype.pluck) {
Object.prototype.pluck = function(...props) {
return props.reduce((destObj, prop) => {
destObj[prop] = this[prop];
return destObj;
}, {});
}
}
const originalObject = {
hello: 'nurse',
meaningOfLife: 42,
your: 'mom',
};
const partialObject2 = originalObject.pluck('hello', 'your');
console.log(partialObject2); // { hello: 'nurse', your: 'mom' }
นี่เป็นทางออกที่สั้นที่สุดและอ่านง่ายที่สุดที่ฉันสามารถหาได้:
let props = {
isValidDate: 'yes',
badProp: 'no!',
};
let { isValidDate } = props;
let newProps = { isValidDate };
console.log(newProps);
มันจะออก { isValidDate: 'yes' }
เป็นเรื่องดีที่บางวันสามารถพูดสิ่งที่ชอบlet newProps = ({ isValidDate } = props)แต่น่าเสียดายที่ไม่ใช่สิ่งที่ ES6 รองรับ
มันไม่ใช่วิธีที่สวยงามหรือฉันไม่แนะนำ แต่เป็นไปได้ด้วยวิธีนี้เพื่อความรู้
const myObject = {
name: 'foo',
surname: 'bar',
year: 2018
};
const newObject = ['name', 'surname'].reduce(
(prev, curr) => (prev[curr] = myObject[curr], prev),
{},
);
console.log(JSON.stringify(newObject)); // {"name":"foo","surname":"bar"}
คุณสามารถใช้วิธีการเรียน JSON เพื่อให้บรรลุดังต่อไปนี้
const foo = {
x: "bar",
y: "baz"
};
const oof = JSON.parse(JSON.stringify(foo, ['x','y']));
// output -> {x: "bar", y: "baz"}
ผ่านคุณสมบัติที่ต้องเพิ่มไปยังวัตถุผลลัพธ์เป็นอาร์กิวเมนต์ที่สองเพื่อstringifyทำงานในรูปแบบอาร์เรย์
Object.assign(oof, foo)