接上文,为手写深拷贝,首先需要了解一些知识,首先如何判断数据类型,我们可能知道typeof可判断数据类型,但其实它只能区分基本类型,即:number、string、undefined、boolean、object。
而对于null、array、function、object来说,使用typeof都会统一返回object
字符串。
要想区分对象{}、数组[]、函数function、单纯使用typeof是不行的。在JS中,可以通过Object.prototype.toString
方法,判断某个对象之属于哪种内置类型。
分为null、string、boolean、number、undefined、array、function、object、date、math。
(作者:公子七
链接:https://www.jianshu.com/p/585926ae62cc
来源:简书)
当然你可以通过下面代码验证各种数据类型是否识别成功。
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call('abc')); // "[object String]"
console.log(Object.prototype.toString.call(123)); // "[object Number]"
console.log(Object.prototype.toString.call(true)); // "[object Boolean]"
深拷贝的思想主要是:
要判断当前拷贝是什么数据类型,来决定函数要返回什么样的数据类型。如果是对象,遍历对象的每一个属性,对每个属性进行克隆。
通过递归的思想来实现,如果确定是对象数据类型之后再判断里面是否还有引用类型的数据,若有则重复之前的步骤直到拷贝对象为基本数据类型。
1、判断数据类型的函数
function cloneType(target){
return Object.prototype.toString.call(target).slice(8,-1);
2、深拷贝
function cloneDeep(target) {
let result;
if (cloneType(target) === 'Object') {
result = {};
} else if (cloneType(target) === 'Array') {
result = [];
} else {
result = target;
}
for (let i in target) {
let item = target[i];
if (cloneType(item) === 'Object' || cloneType(item) === 'Array') {
result[i] = cloneDeep(item);
} else {
result[i] = item;
}
}
return result;
}
检测深拷贝是否生效
oldObj = {
name: 'zhangsan',
age: 13,
option: {
sex: 'man',
fav: 'football',
},
};
let newObj = cloneDeep(oldObj);
console.log(newObj);
console.log('-------------------');
newObj.option = {
sex: 'women',
fav: 'basketball',
};
console.log(oldObj);
只需要检测拷贝后,改变新数组中俄引用类型,旧数组是否跟着改变,如果不改变则深拷贝成功!