Guy*_*Guy 79 javascript ecmascript-6 spread-syntax redux
我正在尝试为我的Redux项目创建一个深度复制映射方法,该方法将使用对象而不是数组.我读到在Redux中,每个州都不应该改变以前的状态.
export const mapCopy = (object, callback) => {
return Object.keys(object).reduce(function (output, key) {
output[key] = callback.call(this, {...object[key]});
return output;
}, {});
}
Run Code Online (Sandbox Code Playgroud)
有用:
return mapCopy(state, e => {
if (e.id === action.id) {
e.title = 'new item';
}
return e;
})
Run Code Online (Sandbox Code Playgroud)
但是它没有深层复制内部项目所以我需要调整它:
export const mapCopy = (object, callback) => {
return Object.keys(object).reduce(function (output, key) {
let newObject = {...object[key]};
newObject.style = {...newObject.style};
newObject.data = {...newObject.data};
output[key] = callback.call(this, newObject);
return output;
}, {});
}
Run Code Online (Sandbox Code Playgroud)
这不太优雅,因为它需要知道传递了哪些对象.ES6中是否有一种方法可以使用扩展语法来深度复制对象?
Nik*_*rao 79
而是将其用于深层复制
var newObject = JSON.parse(JSON.stringify(oldObject))
Run Code Online (Sandbox Code Playgroud)
var oldObject = {
name: 'A',
address: {
street: 'Station Road',
city: 'Pune'
}
}
var newObject = JSON.parse(JSON.stringify(oldObject));
newObject.address.city = 'Delhi';
console.log('newObject');
console.log(newObject);
console.log('oldObject');
console.log(oldObject);
Run Code Online (Sandbox Code Playgroud)
Fra*_*Tan 61
ES6没有内置这样的功能.我认为你有几个选择取决于你想做什么.
如果你真的想要深层复制:
cloneDeep
方法.但是,我想,如果你愿意改变一些事情,你可以节省一些工作.我假设您控制所有呼叫站点到您的功能.
指定传递给的所有回调mapCopy
必须返回新对象,而不是改变现有对象.例如:
mapCopy(state, e => {
if (e.id === action.id) {
return Object.assign({}, e, {
title: 'new item'
});
} else {
return e;
}
});
Run Code Online (Sandbox Code Playgroud)
这Object.assign
用于创建新对象,设置e
该新对象的属性,然后在该新对象上设置新标题.这意味着您永远不会改变现有对象,只在必要时创建新对象.
mapCopy
现在可以很简单:
export const mapCopy = (object, callback) => {
return Object.keys(object).reduce(function (output, key) {
output[key] = callback.call(this, object[key]);
return output;
}, {});
}
Run Code Online (Sandbox Code Playgroud)从本质上讲,mapCopy
是信任其来电者做正确的事情.这就是我说这假设您控制所有呼叫站点的原因.
Abo*_*zlR 28
您可以使用structuredClone()
您可以像下面这样
const myOriginal = {\n title: "Full Stack JavaScript Developer",\n info: {\n firstname: "Javascript",\n surname: " Addicted",\n age: 34\n }\n};\nconst myDeepCopy = structuredClone(myOriginal);\n
Run Code Online (Sandbox Code Playgroud)\n您可以使用structuredClone()
该内置函数进行深度复制。\n结构化克隆解决了许多(尽管不是全部)缺点JSON.stringify()
技术的许多(尽管不是全部)缺点。\n结构化克隆可以处理循环数据结构,\n支持许多内置数据类型,并且通常更稳健并且速度更快。
然而,它仍然有一些限制,可能会让您措手不及:
\n1-原型:如果您使用structuredClone()
与类实例一起使用,\n您\xe2\x80\x99 将获得一个普通对象作为返回值,因为结构化克隆会丢弃对象\xe2\x80\x99s 原型链。
2-功能:如果你的对象包含函数,它们将被悄悄丢弃。
\n3-不可克隆:某些值不是结构化可克隆的,尤其是错误和 DOM 节点。它将导致 StructuredClone() 抛出异常。
\nconst myDeepCopy = structuredClone(myOriginal);\n
Run Code Online (Sandbox Code Playgroud)\n如果您只是想将对象深度复制到另一个对象,\n您需要做的就是JSON.stringify
该对象并使用解析它JSON.parse
随后使用它进行解析。\n这实际上将执行对象的深复制。
let user1 = {\n name: \'Javascript Addicted\',\n age: 34,\n university: {\n name: \'Shiraz Bahonar University\'\n }\n};\n\n\nlet user2 = JSON.parse(JSON.stringify(user1));\n\nuser2.name = \'Andy Madadian\';\nuser2.university.name = \'Kerman Bahonar University\'\n\nconsole.log(user2);\n// { name: \'Andy Madadian\', age: 33, university: { name: \'Kerman Bahonar University\' } }\n\nconsole.log(user1);\n// { name: \'Javascript Addicted\', age: 33, university: { name: \'Shiraz Bahonar University\' } }\n
Run Code Online (Sandbox Code Playgroud)\n在 JavaScript 中使用对象扩展运算符创建浅拷贝的一种方法...或者Object.assign()
如下所示:
const myShallowCopySpread = {...myOriginal};\nconst myShallowCopyObjectAssign=Object.assign({},obj)\n
Run Code Online (Sandbox Code Playgroud)\n当谈到性能时,创建者 Surma 指出,JSON.Parse()
对于小物体来说,速度可能会更快一些。但是当您有一个大对象、复杂对象时\nstructuredClone()
开始变得更快。
浏览器支持非常棒,甚至还受Node.js支持支持。
\nMin*_*uke 23
来自MDN
注意:在复制数组时,Spread语法有效地深入一级.因此,它可能不适合复制多维数组,如下例所示(它与Object.assign()和spread语法相同).
就个人而言,我建议使用Lodash的cloneDeep函数进行多级对象/数组克隆.
这是一个工作示例:
const arr1 = [{ 'a': 1 }];
const arr2 = [...arr1];
const arr3 = _.clone(arr1);
const arr4 = arr1.slice();
const arr5 = _.cloneDeep(arr1);
const arr6 = [...{...arr1}]; // a bit ugly syntax but it is working!
// first level
console.log(arr1 === arr2); // false
console.log(arr1 === arr3); // false
console.log(arr1 === arr4); // false
console.log(arr1 === arr5); // false
console.log(arr1 === arr6); // false
// second level
console.log(arr1[0] === arr2[0]); // true
console.log(arr1[0] === arr3[0]); // true
console.log(arr1[0] === arr4[0]); // true
console.log(arr1[0] === arr5[0]); // false
console.log(arr1[0] === arr6[0]); // false
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
Run Code Online (Sandbox Code Playgroud)
我经常使用这个:
function deepCopy(obj) {
if(typeof obj !== 'object' || obj === null) {
return obj;
}
if(obj instanceof Date) {
return new Date(obj.getTime());
}
if(obj instanceof Array) {
return obj.reduce((arr, item, i) => {
arr[i] = deepCopy(item);
return arr;
}, []);
}
if(obj instanceof Object) {
return Object.keys(obj).reduce((newObj, key) => {
newObj[key] = deepCopy(obj[key]);
return newObj;
}, {})
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
const a = {
foods: {
dinner: 'Pasta'
}
}
let b = JSON.parse(JSON.stringify(a))
b.foods.dinner = 'Soup'
console.log(b.foods.dinner) // Soup
console.log(a.foods.dinner) // Pasta
Run Code Online (Sandbox Code Playgroud)
使用JSON.stringify
andJSON.parse
是最好的方法。因为当 json 对象内部包含另一个对象时,通过使用展开运算符,我们将无法得到有效的答案。我们需要手动指定。
归档时间: |
|
查看次数: |
80557 次 |
最近记录: |