JavaScript中的对象和数组复制可以使用浅拷贝和深拷贝的概念。在进行对象和数组复制时,使用的是复制原始值,而不是将原始值的引用作为新值传递。
浅拷贝
浅拷贝会创建一个新的对象或数组,然后将原始对象或数组的所有属性或元素复制到新的对象或数组中。新对象或数组中的属性或元素仍然指向原始对象或数组中的相同值。
创建浅拷贝有多种方法,其中最常见的方法是使用展开运算符或Object.assign()方法。
展开运算符
var original = {name: "alice", hobbies: ["reading", "swimming"]};
var copy = {...original};
// 等价于
// var copy = Object.assign({}, original);
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}
original.name = "bob";
original.hobbies[0] = "watching TV";
console.log(copy); // {name: "alice", hobbies: ["watching TV", "swimming"]}
此示例中,使用展开运算符将original对象复制到copy对象中。修改原始对象的值将不会影响副本对象中的值。但是,修改原始对象中数组的元素值会反映在副本对象中的数组中。
Object.assign()
var original = {name: "alice", hobbies: ["reading", "swimming"]};
var copy = Object.assign({}, original);
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}
original.name = "bob";
original.hobbies[0] = "watching TV";
console.log(copy); // {name: "alice", hobbies: ["watching TV", "swimming"]}
此示例中,使用Object.assign()将original对象复制到copy对象中。修改原始对象的值将不会影响副本对象中的值。但是,修改原始对象中数组的元素值会反映在副本对象中的数组中。
深拷贝
深拷贝会创建一个新的对象或数组,并将原始对象或数组中的所有属性或元素复制到新的对象或数组中。如果原始对象或数组中的属性或元素是对象或数组,则该属性或元素也将复制为新的对象或数组。
创建深层复制有多种方法,其中常见的方法是使用JSON.parse(JSON.stringify())、lodash库或递归函数。
JSON.parse(JSON.stringify())
var original = {name: "alice", hobbies: ["reading", "swimming"]};
var copy = JSON.parse(JSON.stringify(original));
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}
original.name = "bob";
original.hobbies[0] = "watching TV";
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}
此示例中,在原始对象上调用JSON.stringify()将其序列化为JSON字符串,然后再次调用JSON.parse()将其反序列化为JavaScript对象。新的copy对象包含与original对象相同的值,但它们指向不同的内存位置。修改原始对象的值将不会影响副本对象中的值。
但是,JSON.stringify()不能序列化undefined、正则表达式、函数、Symbol和其他可以在对象中使用的特殊对象类型,例如Map和Set。
lodash库
var _ = require("lodash");
var original = {name: "alice", hobbies: ["reading", "swimming"]};
var copy = _.cloneDeep(original);
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}
original.name = "bob";
original.hobbies[0] = "watching TV";
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}
这个实例中,使用lodash库的_.cloneDeep()函数创建一个深层复制。lodash库可以工作在客户端和服务器端,并处理函数、Symbol等对象类型。
递归函数
function deepClone(obj) {
if (typeof obj !== "object" || obj === null) {
return obj;
}
var clone = Array.isArray(obj) ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key]);
}
}
return clone;
}
var original = {name: "alice", hobbies: ["reading", "swimming"]};
var copy = deepClone(original);
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}
original.name = "bob";
original.hobbies[0] = "watching TV";
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}
这个实例中,定义了一个名为deepClone()的递归函数,它处理对象和数组并返回其副本。如果传递给它的参数不是对象或数组,则直接返回参数。如果是对象或数组,则遍历它并复制其属性或元素。递归深度克隆对象,以便包含的对象和数组也被深度克隆。
上述函数可以实现数组的深拷贝,但是,当对象属性中含有函数或正则表达式等特殊类型时,可能出现问题。
以上是关于JavaScript基础心法深浅拷贝的完整攻略。其中包含了浅拷贝与深拷贝的定义、实现方式的详细讲解以及多个示例来说明相关概念的使用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript基础心法 深浅拷贝(浅拷贝和深拷贝) - Python技术站