คำตอบ:
นี่คือวิธีextend
/ การassign
ทำงาน: สำหรับแต่ละคุณสมบัติในแหล่งที่มาให้คัดลอกค่าตามที่เป็นไปยังปลายทาง หากค่าคุณสมบัติเป็นวัตถุเองก็จะไม่มีคุณสมบัติการแวะเวียนแบบเรียกซ้ำ วัตถุทั้งหมดจะถูกนำมาจากแหล่งที่มาและกำหนดไว้ในปลายทาง
นี่เป็นวิธีการmerge
ทำงาน: สำหรับแต่ละคุณสมบัติในแหล่งข้อมูลให้ตรวจสอบว่าคุณสมบัตินั้นเป็นวัตถุเอง ถ้าเป็นไปแล้วซ้ำและพยายามแมปคุณสมบัติวัตถุลูกจากต้นทางไปยังปลายทาง ดังนั้นเราจึงรวมลำดับชั้นของวัตถุจากต้นทางไปยังปลายทาง ในขณะที่สำหรับextend
/ assign
มันเป็นสำเนาของคุณสมบัติในระดับง่าย ๆ จากต้นทางไปยังปลายทาง
นี่คือ JSBin ง่าย ๆ ที่จะทำให้คริสตัลนี้ใส: http://jsbin.com/uXaqIMa/2/edit?js,console
นี่คือเวอร์ชั่นที่ซับซ้อนยิ่งขึ้นซึ่งรวมถึงอาเรย์ในตัวอย่างด้วย: http://jsbin.com/uXaqIMa/1/edit?js,console
var combined = merge({}, src, dest)
_.merge(object, [sources], [customizer], [thisArg])
_.assign(object, [sources], [customizer], [thisArg])
_.extend(object, [sources], [customizer], [thisArg])
_.defaults(object, [sources])
_.defaultsDeep(object, [sources])
_.extend
เป็นชื่อแทน_.assign
ดังนั้นจึงเหมือนกันnull
เดียวกัน_.defaults
และ_.defaultsDeep
ประมวลผลข้อโต้แย้งในลำดับย้อนกลับเมื่อเปรียบเทียบกับข้ออื่น (แม้ว่าอาร์กิวเมนต์แรกยังเป็นวัตถุเป้าหมาย)_.merge
และ_.defaultsDeep
จะรวมวัตถุลูกและวัตถุอื่น ๆ จะเขียนทับในระดับราก_.assign
และ_.extend
จะเขียนทับค่าด้วยundefined
_.assign ({}, { a: 'a' }, { a: 'bb' }) // => { a: "bb" }
_.merge ({}, { a: 'a' }, { a: 'bb' }) // => { a: "bb" }
_.defaults ({}, { a: 'a' }, { a: 'bb' }) // => { a: "a" }
_.defaultsDeep({}, { a: 'a' }, { a: 'bb' }) // => { a: "a" }
_.assign
จับundefined
แต่คนอื่น ๆ จะข้ามมัน_.assign ({}, { a: 'a' }, { a: undefined }) // => { a: undefined }
_.merge ({}, { a: 'a' }, { a: undefined }) // => { a: "a" }
_.defaults ({}, { a: undefined }, { a: 'bb' }) // => { a: "bb" }
_.defaultsDeep({}, { a: undefined }, { a: 'bb' }) // => { a: "bb" }
null
เดียวกัน_.assign ({}, { a: 'a' }, { a: null }) // => { a: null }
_.merge ({}, { a: 'a' }, { a: null }) // => { a: null }
_.defaults ({}, { a: null }, { a: 'bb' }) // => { a: null }
_.defaultsDeep({}, { a: null }, { a: 'bb' }) // => { a: null }
_.merge
และ_.defaultsDeep
จะรวมวัตถุลูก_.assign ({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "b": "bb" }}
_.merge ({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "a": "a", "b": "bb" }}
_.defaults ({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "a": "a" }}
_.defaultsDeep({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "a": "a", "b": "bb" }}
_.assign ({}, {a:['a']}, {a:['bb']}) // => { "a": [ "bb" ] }
_.merge ({}, {a:['a']}, {a:['bb']}) // => { "a": [ "bb" ] }
_.defaults ({}, {a:['a']}, {a:['bb']}) // => { "a": [ "a" ] }
_.defaultsDeep({}, {a:['a']}, {a:['bb']}) // => { "a": [ "a" ] }
a={a:'a'}; _.assign (a, {b:'bb'}); // a => { a: "a", b: "bb" }
a={a:'a'}; _.merge (a, {b:'bb'}); // a => { a: "a", b: "bb" }
a={a:'a'}; _.defaults (a, {b:'bb'}); // a => { a: "a", b: "bb" }
a={a:'a'}; _.defaultsDeep(a, {b:'bb'}); // a => { a: "a", b: "bb" }
หมายเหตุ: ตามที่ @Mistic ชี้ให้เห็นว่า Lodash ใช้อาร์เรย์เป็นวัตถุที่มีคีย์เป็นดัชนีในอาร์เรย์
_.assign ([], ['a'], ['bb']) // => [ "bb" ]
_.merge ([], ['a'], ['bb']) // => [ "bb" ]
_.defaults ([], ['a'], ['bb']) // => [ "a" ]
_.defaultsDeep([], ['a'], ['bb']) // => [ "a" ]
_.assign ([], ['a','b'], ['bb']) // => [ "bb", "b" ]
_.merge ([], ['a','b'], ['bb']) // => [ "bb", "b" ]
_.defaults ([], ['a','b'], ['bb']) // => [ "a", "b" ]
_.defaultsDeep([], ['a','b'], ['bb']) // => [ "a", "b" ]
_.extend is an alias for _.assign, so they are identical
ขัดแย้งกับOnly _.assign will overwrite a value with undefined
ข้อแตกต่างอีกประการที่ควรคำนึงถึงคือการจัดการundefined
ค่า:
mergeInto = { a: 1}
toMerge = {a : undefined, b:undefined}
lodash.extend({}, mergeInto, toMerge) // => {a: undefined, b:undefined}
lodash.merge({}, mergeInto, toMerge) // => {a: 1, b:undefined}
ดังนั้นmerge
จะไม่รวมundefined
ค่าเป็นค่าที่กำหนด
mergeInto
มีคุณสมบัติที่toMerge
ไม่ได้มีก็จะรักษาคุณสมบัติเหล่านั้น ในกรณีนี้มันจะไม่ลอกแบบ
การพิจารณาสิ่งที่พวกเขาทำจากมุมมองทางความหมายอาจเป็นประโยชน์เช่นกัน
will assign the values of the properties of its second parameter and so on,
as properties with the same name of the first parameter. (shallow copy & override)
merge is like assign but does not assign objects but replicates them instead.
(deep copy)
provides default values for missing values.
so will assign only values for keys that do not exist yet in the source.
works like _defaults but like merge will not simply copy objects
and will use recursion instead.
ฉันเชื่อว่าการเรียนรู้ที่จะคิดวิธีการเหล่านั้นจากมุมมองเชิงความหมายจะช่วยให้คุณ "คาดเดา" ได้ดีขึ้นว่าอะไรจะเป็นพฤติกรรมสำหรับสถานการณ์ที่แตกต่างกันทั้งหมดของค่าที่มีอยู่และไม่ได้มีอยู่
หากคุณต้องการสำเนาลึกที่ไม่มีการแทนที่ในขณะที่ยังคงมีobj
การอ้างอิงเดียวกัน
obj = _.assign(obj, _.merge(obj, [source]))