拷贝:所谓拷贝,就是赋值。把一个变量赋给另外一个变量,就是把变量的内容进行拷贝。把一个对象的值赋给另外一个对象,就是把一个对象拷贝一份。
浅拷贝:复制出的这个结果数据,如果发生变化,会影响原数据。
下面为大家罗列出集中常见的浅拷贝例子
浅拷贝:直接复制
var arr1=[1,2,3,4]
const newArr=arr1
newArr[0]=520
console.log(arr1)
console.log(newArr)
浅拷贝:concat() 方法用于连接两个或多个数组。
let arr = [{name:'张三'},1,2,3,4];
let newArr = [].concat(arr);
newArr[0].name = '李四';
console.log(arr)
console.log(newArr)
浅拷贝:slice(数组中截取的一种方法)
let arr = [{name:'张三'},1,2,3,4];
let newArr = arr.slice(0);
newArr[0].name = '李四';
console.log(arr)
console.log(newArr)
浅拷贝:ES6扩展运算符
let arr = [{name:'张三'},1,2,3,4];
let newArr = [...arr];
newArr[0].name = '王五';
console.log(arr)
console.log(newArr)
浅拷贝:使用 assign 方法创建对象 (assign 对象的合并)
const school = {
name: "张三",
pos: ['北京','上海','深圳']
}
const newSchool = Object.assign({}, school);
newSchool.pos[0] = 'beijing';
console.log(school);
console.log(newSchool);
深拷贝:复制出的这个结果数据,对他进行任何操作,跟原数据不会发生任何影响。(完全独立新的数据产生)
深拷贝(JSON)实现
//JSON 实现深拷贝
// stringify 将 JS 对象转化为 JSON 格式的字符串
// parse 将 JSON 格式的字符串转化为 JS 对象
//缺陷: 不能复制方法
const school = {
name: '许昌学院',
pos: '河南许昌',
study() {
console.log('学习')
}
}
//将对象转化为JSON字符串
let str = JSON.stringify(school)
// 将JSON字符串转换为jS对象
let newSchool = JSON.parse(str)
newSchool.pos = 'henanxuchang'
console.log(school)
console.log(newSchool)
深拷贝:递归实现深拷贝的思路
const school = {
name: '许昌学院',
pos: ['北京','上海','深圳'],
founder:
{
name: '前端'
},
change: function(){
console.log('改变');
}
}
//创建数据容器
const newSchool = {};
//name
newSchool.name = school.name;
//pos
newSchool.pos = school.pos;
newSchool.pos = [];
newSchool.pos[0] = school.pos[0];
newSchool.pos[1] = school.pos[1];
newSchool.pos[2] = school.pos[2];
//founder
newSchool.founder = {};
newSchool.founder.name = school.founder.name;
//方法:通过bind改变this指向,并把新函数赋值给newSchool.change
newSchool.change = school.change.bind(newSchool);
newSchool.pos[0] = 'beijing';
console.log(school);
console.log(newSchool);
深拷贝:封装一个深拷贝函数
//封装一个函数
function deepClone(data){
//创建一个容器 typeof
let container;
//判断
let type = getDataType(data);// Object Array
//如果是对象类型,让container为一个空对象
if(type === 'Object'){
container = {};
}
//如果是数组类型,让container为一个新数组
if(type === 'Array'){
container = [];
}
//遍历数据 for...in
for(let i in data){
//获取键值的类型
let type = getDataType(data[i]);// Array
if(type === 'Array' || type==='Object'){
// 递归调用 deepClone 即可
container[i] = deepClone(data[i]);
}else{
//如果键值为非引用类型数据 则『直接复制』
container[i] = data[i];
}
}
//container
return container;
}
//待克隆的数据
const school = {
name: '许昌',
pos: ['北京','上海','深圳'],
founder: {
name: '前端'
},
change: function(){
console.log('改变');
}
}
//调用函数完成深拷贝
const newSchool = deepClone(school);
newSchool.pos[0] = 'beijing';
console.log(school);
console.log(newSchool);
//封装一个函数 用来获取数据的类型
function getDataType(data){
//判断基本数据类型,并截取
return Object.prototype.toString.call(data).slice(8, -1);
}
好了,如果能独立的封装出一个深拷贝的函数的话,以后想要拷贝出一个一模一样的数据直接去调用这个函数就可以了。