应用场景:
现有一个数组Array对象,需要在两个不同模块上展示,分别为模块A和模块B,现需求为模块A循环展示Array的所有信息,模块B在Array的基础之上添加一个字段,且不影响字段A的正常展示最终效果如下
实现分析:
原始数据(暂定数组名称为listArray1)和拷贝后的数据(暂定数组名称为listArray2)都有一部分相似的数据,唯一区别就是拷贝后的数据中添加了一条,所以我们很容易将listArray1赋值给listArray2然后push({name:'张三5',age:15,sex:'男'})这么一条数据。
我们可以是实际操作看,以上这种方法在改变了拷贝后的数据(listArray2)的同时,也不经意间改变了原始数据(listArray1),这种方法就和我们的需求背道而驰了,所以这里我们就将用到js的深浅拷贝。划重点:何为深拷贝何为浅拷贝
定义:
浅拷贝:将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用
深拷贝:创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”
备注:(深浅拷贝就相当于去书店买书和借书一样,买了就是你的;借的还是需要还的,书还是书店的,区别在于归谁所有)
深度解析:
综上所述,如果要想实现拷贝后的数据(listArray2)变化后,原始数据(listArray1)不变,就需要给拷贝后的数据(listArray2)开辟一个新的内存空间(返回一个新的数组),所以熟悉数组中方法的同学就知道,能返回新数组的方法有如下几个:
concat() | 连接两个或更多的数组,并返回结果。 |
slice() | 从某个已有的数组返回选定的元素 |
所以我们可以用一下的代码实现
<template>
<div class="copy">
<h1>我是原始数据</h1>
<ul>
<li v-for="(list , index) in listArray1" :key="index" >我是{{list.name}},我今年{{list.age}},我是{{list.sex}}的</li>
</ul>
<h1>我是拷贝之后的数据</h1>
<ul>
<li v-for="(list , index) in listArray2" :key="index" >我是{{list.name}},我今年{{list.age}},我是{{list.sex}}的</li>
</ul>
</div>
</template>
<script>
export default {
name: 'copy',
data () {
return {
listArray1:[
{name:'张三1',age:12,sex:'男'},
{name:'张三2',age:12,sex:'男'},
{name:'张三3',age:13,sex:'男'},
{name:'张三4',age:13,sex:'男'},
],
listArray2:[],
}
},
mounted(){
this.listArray2 = this.listArray1.slice(); //返回一个新的数组
this.listArray2.push({name:'张三5',age:15,sex:'男'});
},
}
</script>
升级打怪:
除了用this.listArray2 = this.listArray1.slice(); 这种方式我们还可以用ES6扩展运算符
this.listArray2 = [...this.listArray1 , {name:'张三5',age:15,sex:'男'}];
现需要在js中,使用一个新的对象的值覆盖旧有对象,js中有一个方法:
Object.assign(target,…sources)
当target和sources对象中有相同的key时,在target对象中的值会被后面source对象的值覆盖。
var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };
var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, target对象自身会被修改
如果想要避免o1被改变,需要这样写:
var obj = Object.assign({},o1,o2,o3);//给一个空对象作为target,这样改变的是空对象
console.log(obj);// { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1}
以上信息均为手打,如有不足之处,还望留言指正,谢谢!