[转][基础]javascript之浅拷贝、深拷贝、全相等
JS 基础,浅拷贝深拷贝,理解下引用类型,比较简单,原文链接:juejin.cn/post/6928637773939376135 ,作者:明洁
不管是浅拷贝,还是深拷贝,都只针对引用数据类型。
- 浅拷贝:拷贝对象的第一层属性,但是对于更深层次的属性只是复制引用地址,而不是对象本身,新旧对象共享同一个内存地址。
// 需要拷贝的对象
const data = {
name:"奥特曼",
info:{
age:12,
relationShip:['one','two']
},
arr:['艾斯','泰罗']
}
// 浅拷贝对象
const cloneData = Object.assign({},data);
// 浅拷贝结果
console.log(data === cloneData) // false;
console.log(data.info === cloneData.info) // true;
console.log(data.info.relationShip === cloneData.info.relationShip) // true;
console.log(data.arr === cloneData.arr) // true;
// 当我改变浅拷贝对象的属性时
cloneData.name = "哈哈哈哈";
clone.info.age = 99;
console.log(data.name) // 奥特曼
console.log(data.info.age) // 99
- 深拷贝:拷贝对象的每一层属性,创建一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
// 需要拷贝的对象
const data = {
name:"奥特曼",
info:{
age:12,
relationShip:['one','two']
},
arr:['艾斯','泰罗']
}
// 深拷贝对象
const cloneData = deepClone(data);
// 深拷贝结果
console.log(data === cloneData) // false;
console.log(data.info === cloneData.info) // false;
console.log(data.info.relationShip === cloneData.info.relationShip) // false;
console.log(data.arr === cloneData.arr) // false;
// 当我改变深拷贝对象的属性时
cloneData.name = "哈哈哈哈";
clone.info.age = 99;
console.log(data.name) // 奥特曼
console.log(data.info.age) // 12
深拷贝实现
深拷贝只针对引用数据类型,首先要对数据类型做个判断
// 判断是否是undefined
function isUndefined(data) {
return data === undefined;
}
// 判断是否是Null
function isNull(data) {
return data === null;
}
// 判读是否是number string boolean基本数据类型
function isBaseType(data) {
const type = typeof data;
const baseType = ["string", "number", "boolean"];
return (
baseType.findIndex((v) => v === type) > -1 ||
isUndefined(data) ||
isNull(data)
);
}
// 判断是否是数组类型
function isArray(data) {
return data instanceof Array;
}
// 深拷贝具体实现
function deepCopy(data) {
if (isBaseType(data)) return data;
let object = {};
if (isArray(data)) object = [];
for (let key in data) {
object[key] = deepCopy(data[key]);
}
return object;
}
实现全比较equal
function equal(data1, data2) {
// 如果两个数据当中有一个是基本数据类型
if (isBaseType(data1) || isBaseType(data2)) {
return data1 === data2;
}
// 当引用数据类型的地址值相同时
if (data1 === data2) return true;
// 当引用数据类型的地址值不同时
const data1_keys = Object.keys(data1);
const data2_keys = Object.keys(data2);
if (data1_keys.length !== data2_keys.length) {
return false;
}
for (let key in data1) {
const result = equal(data1[key], data2[key]);
if (!result) return false;
}
return true;
}