回顾:
浅拷贝:两个数据之间存在堆内存的引用,一个数据修改了另一个数据也被修改。
深拷贝:两个数据之间是完全独立的,不存在堆内存的引用。一个数据修改了另一个数据不发生改变。
题目要求:有已知以下某公司员工薪金信息,把每一位员工的salary薪金信息 加 2000,并返回新数组,注意:不影响原数组
var persons = [
{
username:'张飞',
sex:'男',
salary:50000
},
{
username:'关羽',
sex:'男',
salary:60000
}
]
思路分析:persons是个数组,且要修改每一位员工的薪金信息,用到数组迭代方法,且要对数组中的每一项进行操作,所以选择map方法。
此时理所当然的会把代码写成这样:
var res = persons.map(function(val,index){
val.salary += 2000
return val
})
console.log(res)
控制台输出为:
看着是改了没错,但是一旦对res这个新数组进行操作,原数组persons也会进行修改。
//将res的第一项中属性名为username的属性值改为测试
res[0].username = "测试";
//打印res
console.log(res)
//打印persons
console.log(persons)
控制台输出结果为:
可以看出res的改变把原数组persons也改了。
这是因为在 var res = persons.map(function(val,index){...}时,persons其实是把地址给了res,所以二者之间是浅拷贝的关系。也可以说res和persons指向同一个地址。
但是题目要求不影响原数组,所以我们需要进行深拷贝的操作,也就是将res数组中的对象设置为独立的对象,这时就需要重新创建对象。
var res = persons.map(function (val, index) {
//以对象形式返回
return { username: val.username, sex: val.sex, salary: val.salary + 2000 }
})
此时再修改res[0]的username值就修改的是res数组中的值了。
就实现了深拷贝,不会影响原数组。
控制台输出如下:
完整代码为:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var persons = [
{
username: '张飞',
sex: '男',
salary: 50000
},
{
username: '关羽',
sex: '男',
salary: 60000
}
];
var res = persons.map(function (val, index) {
return { username: val.username, sex: val.sex, salary: val.salary + 2000 }
})
res[0].username = "测试";
console.log(res)
console.log(persons)
</script>
</body>
</html>