JavaScript 深度复制包含嵌套对象、数组和函数的数组?
JavaScript deep copy an array containing nested objects, arrays & functions?
我有一个结构如下的数组,我正在尝试获取它的副本(以修改和用于 React setState())。在 Python 中我可以使用 copy.deepcopy() 但我在 JavaScript.
中找不到简单的方法
notes=[
{
contents: "Hello World 1",
function: console.log,
children: [
{
contents: "Hello World A",
function: console.log,
children: []
},
]
},
{
contents: "Hello World 2",
function: console.log,
children: []
}
]
我在 Whosebug 上找到了这篇文章和类似的解决方案,但其中 none 对我有用。
https://medium.com/@Farzad_YZ/3-ways-to-clone-objects-in-javascript-f752d148054d
两个方案只是浅拷贝,JSON.parse对函数不起作用
我想要一个可以深度复制任何数组或对象的函数,其中包含嵌套 JavaScript 数据类型的任意结构。
我不想重新发明轮子,写一个复杂的递归函数来遍历和克隆所有东西,有现成的解决方案吗?
编辑- 您可以使用下面的解决方案或只导入 Lodash 并使用此 https://lodash.com/docs/#cloneDeep
我正在用找到的解决方案回答我自己的问题。有人在我链接的文章的评论部分发布了这个,它似乎有效
notes=[
{
contents: "Hello World 1",
function: console.log,
children: [
{
contents: "Hello World A",
function: console.log,
children: []
},
]
},
{
contents: "Hello World 2",
function: console.log,
children: []
}
]
function deepCopy(src) {
let target = Array.isArray(src) ? [] : {};
for (let key in src) {
let v = src[key];
if (v) {
if (typeof v === "object") {
target[key] = deepCopy(v);
} else {
target[key] = v;
}
} else {
target[key] = v;
}
}
return target;
}
如果找不到更好的答案,最短的方法
var note2 = JSON.parse(JSON.stringify(notes))
但它没有复制函数
所以检查
function iterationCopy(src) {
let target = {};
for (let prop in src) {
if (src.hasOwnProperty(prop)) {
target[prop] = src[prop];
}
}
return target;
}
const source = {a:1, b:2, c:3};
const target = iterationCopy(source);
console.log(target); // {a:1, b:2, c:3}
// Check if clones it and not changing it
source.a = 'a';
console.log(source.a); // 'a'
console.log(target.a); // 1
和
function bestCopyEver(src) {
return Object.assign({}, src);
}
const source = {a:1, b:2, c:3};
const target = bestCopyEver(source);
console.log(target); // {a:1, b:2, c:3}
// Check if clones it and not changing it
source.a = 'a';
console.log(source.a); // 'a'
console.log(target.a); // 1
应该用for循环迭代判断item类型,如果是object类型就用递归。功能如:
function copy(obj1, obj2) {
var obj2=obj2||{};
for(var name in obj1) {
if(typeof obj1[name] === "object") {
obj2[name]= (obj1[name].constructor===Array)?[]:{};
copy(obj1[name],obj2[name]);
} else {
obj2[name]=obj1[name];
}
}
return obj2;
}
我有一个结构如下的数组,我正在尝试获取它的副本(以修改和用于 React setState())。在 Python 中我可以使用 copy.deepcopy() 但我在 JavaScript.
中找不到简单的方法notes=[
{
contents: "Hello World 1",
function: console.log,
children: [
{
contents: "Hello World A",
function: console.log,
children: []
},
]
},
{
contents: "Hello World 2",
function: console.log,
children: []
}
]
我在 Whosebug 上找到了这篇文章和类似的解决方案,但其中 none 对我有用。 https://medium.com/@Farzad_YZ/3-ways-to-clone-objects-in-javascript-f752d148054d 两个方案只是浅拷贝,JSON.parse对函数不起作用
我想要一个可以深度复制任何数组或对象的函数,其中包含嵌套 JavaScript 数据类型的任意结构。
我不想重新发明轮子,写一个复杂的递归函数来遍历和克隆所有东西,有现成的解决方案吗?
编辑- 您可以使用下面的解决方案或只导入 Lodash 并使用此 https://lodash.com/docs/#cloneDeep
我正在用找到的解决方案回答我自己的问题。有人在我链接的文章的评论部分发布了这个,它似乎有效
notes=[
{
contents: "Hello World 1",
function: console.log,
children: [
{
contents: "Hello World A",
function: console.log,
children: []
},
]
},
{
contents: "Hello World 2",
function: console.log,
children: []
}
]
function deepCopy(src) {
let target = Array.isArray(src) ? [] : {};
for (let key in src) {
let v = src[key];
if (v) {
if (typeof v === "object") {
target[key] = deepCopy(v);
} else {
target[key] = v;
}
} else {
target[key] = v;
}
}
return target;
}
如果找不到更好的答案,最短的方法
var note2 = JSON.parse(JSON.stringify(notes))
但它没有复制函数
所以检查
function iterationCopy(src) {
let target = {};
for (let prop in src) {
if (src.hasOwnProperty(prop)) {
target[prop] = src[prop];
}
}
return target;
}
const source = {a:1, b:2, c:3};
const target = iterationCopy(source);
console.log(target); // {a:1, b:2, c:3}
// Check if clones it and not changing it
source.a = 'a';
console.log(source.a); // 'a'
console.log(target.a); // 1
和
function bestCopyEver(src) {
return Object.assign({}, src);
}
const source = {a:1, b:2, c:3};
const target = bestCopyEver(source);
console.log(target); // {a:1, b:2, c:3}
// Check if clones it and not changing it
source.a = 'a';
console.log(source.a); // 'a'
console.log(target.a); // 1
应该用for循环迭代判断item类型,如果是object类型就用递归。功能如:
function copy(obj1, obj2) {
var obj2=obj2||{};
for(var name in obj1) {
if(typeof obj1[name] === "object") {
obj2[name]= (obj1[name].constructor===Array)?[]:{};
copy(obj1[name],obj2[name]);
} else {
obj2[name]=obj1[name];
}
}
return obj2;
}