方法一:
采用递归的方式进行
<script type="text/javascript">
function Person(name, age) {
this.name = name;
this.age = age;
this.hobby = ['唱', '跳', 'rap']
this.girlFriend = {
nickname: '乔碧萝',
arr: ['吃', '写代码', '榜一大哥', [1, 2, 3, 4, 6, { skill: '飞' }]]
}
}
let p1 = new Person('李雷', 20);
console.log(p1);// Object { name: "李雷", age: 20, hobby: (3) […], girlFriend: {…} }
//采用递归的方式,对对象进行深拷贝
//需求:拷贝p1
// //data就是要进行拷贝的对象
function deepCopy(data) {
let newObj = {};//声明一个对象用于拷贝原来的对象属性
let arr = [];//用于拷贝数组
//进行一个判断,判断data是不是一个引用数据类型
//要区分是数组还是对象
//是一个对象的情况下
if (typeof data === 'object' && !Array.isArray(data)) {
for (k in data) {
//判断 如果某个属性值是引用数据类型
if (typeof data[k] === "object") { //遍历数据data,如果data的某个元素仍然为一个对象
newObj[k] = deepCopy(data[k]) //则让着对象中的数值赋值到这个空数组中
} else {
newObj[k] = data[k]
}
}
return newObj //返回这个拷贝完成的新对象,
} else if (Array.isArray(data)) { //是一个数组的情况下
// data= ['唱', '跳', 'rap']
for (let i = 0; i < data.length; i++) {
//拷贝多维数组
if (typeof data[i] === 'object') { //表示如果这个与数据中的某个元素仍为一个数组
arr.push(deepCopy(data[i])) //则将这个数组,推到这个arr中
} else {
arr.push(data[i])
}
}
return arr
}
}
let p2 = deepCopy(p1)//拷贝p1结束后,将拷贝的值赋给p2
console.log(p2);//打印p2,此时打印的值和p1的值是一样的
p2.name = '小明'//将p2外层为name的键的值,改为小明
p2.girlFriend.nickname = '55开'//将p2外层键为girlFriend的,这个对象下的键为nickname的值改为55开
p2.girlFriend.arr.push("999")//将p2外层键为girlFriend的,这个对象下的键为arr的,这个数组,增加一个元素999
p2.girlFriend.arr[3].push('888')//将p2外层键为girlFriend的,这个对象下的键为arr的,这个数组下的索引为3的数组,增加一个为888的元素
p2.girlFriend.arr[3][5].bodyFriend = '建军'//将p2外层键为girlFriend的,这个对象下的键为arr的,这个数组下的索引为3的数组下的索引为5的对象增加一个键为bodyFriend 值为 '建军'
console.log("p1==========", p1);//此时打印的p1的结果不变
console.log("p2==========", p2);//此时打印的p2的结果发生了上面的变化
//之所以发生了上面的变化是因为深拷贝全部的值都进行了拷贝
</script>
深拷贝的封装:
<script type="text/javascript">
//采用递归的方式,对对象进行深拷贝
//需求:拷贝p1
// //data就是要进行拷贝的对象
function deepCopy(data) {
let newObj = {}; //声明一个对象用于拷贝原来的对象属性
let arr = []; //用于拷贝数组
//进行一个判断,判断data是不是一个引用数据类型(复杂数据类型)
//要区分是数组还是对象
if (typeof data === 'object' && !Array.isArray(data)) {
//!Array.isArray(data)表示data不是个数组
// Array.isArray(object) 返回值是布尔类型的。
// 如果传进来的object是数组,返回true,如果不是数组,则返回false。
for (k in data) { //遍历这个对象
//判断 如果某个属性值是引用数据类型
if (typeof data[k] === "object") { //表示如果这个数组中的某个元素为对象
newObj[k] = deepCopy(data[k])
} else {
newObj[k] = data[k]
}
}
return newObj
} else if (Array.isArray(data)) {
for (let i = 0; i < data
.length; i++) { //拷贝多维数组 if (typeof data[i]==='object' ) { arr.push(deepCopy(data[i])) } else
{
arr.push(data[i])
}
}
return arr
}
}
let p2 = deepCopy(p1) //拷贝p1结束后,将拷贝的值赋给p2 console.log(p2);
</script>
方法二:
1.JSON.stringify(),先将对象或数组转换为json字符串格式
2.JSON.parse() 再将其转换为数组或对象
<script>
let o1 = {
name: '建军',
age: 19,
girlFriend: {
name: '李溪芮'
}
}
//转成JSON字符串
let o2 = JSON.stringify(o1); //将对象o1转化为json字符串
//再转成对象
o2 = JSON.parse(o2) //将json字符串转换为对象
o2.girlFriend.name = '乔碧萝'
console.log(o1);
/* 打印结果为Object { name: "建军", age: 19, girlFriend: {…} }
age: 19
girlFriend: Object { name: "李溪芮" }
name: "建军" */
console.log(o2);
/*打印结果为 Object { name: "建军", age: 19, girlFriend: {…} }
age: 19
girlFriend: Object { name: "乔碧萝" }
name: "建军" */
</script>