深拷贝,就是开辟一个空间,并且进行赋值,而不是把引用地址进行赋值(浅拷贝)
方法1
JSON.parse(JSON.stringify(obj))
但是是有缺点的,直接贴代码,详情见注释:
let a = {
b: [],//数组
c: {
},//对象
d: 1, //基本类型
e: null,//typeof null === 'object'
f: undefined,//类型为undefined
g: function(){
console.log('函数')
},
h: new Date()
}
// 使用JSON.parse的方式来进行深拷贝
// 但是还是有不足的地方,比如会自动忽略undefined和函数
// 而且对Date类型也不是很友好,会转化成字符串,是date格式的意义
// 并且对于继承的类型没办法进行克隆
// function Person(){}
// Person.prototype.name = 'zaw'
// let p = new Person()
const cloneObj = JSON.parse(JSON.stringify(p))
console.log(cloneObj,p)
无法克隆继承来的属性,结果如下:
知识点1:
在判断js中的类型的时候,有typeof,custryctor,instanceof,Object.prototype.toString(),四种方法。其中最完美的方法是,Object.prototype.toString.call(obj)方法,解释如下:
所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是任意值,甚至可以是内置对象使用过的[[Class]]属性的值.[[Class]]属性的值可以用来判断一个原生对象属于哪种内置类型.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值(查看 15.2.4.2).
也就是说,把Object.prototype.toString方法返回的字符串,去掉前面固定的"[object “和后面固定的”]",就是内部属性[[class]]的值,也就达到了判断对象类型的目的.jQuery中的工具方法$.type(),就是干这个的.
在ES3中,规范文档并没有总结出[[class]]内部属性一共有几种,不过我们可以自己统计一下,原生对象的[[class]]内部属性的值一共有10种.分别是:“Array”, “Boolean”, “Date”, “Error”, “Function”, “Math”, “Number”, “Object”, “RegExp”, “String”.
知识点2:
再来介绍一种判断空的方法,基本类型直接判空,对象{},数组,可以时候用JSON.stringify(obj) === ‘{}’ || JSON.stringify(obj) === ‘[]’
我们来写一个一般人写的深拷贝:
let a = {
b: [],//数组
c: {
},//对象
d: 1, //基本类型
e: null,//typeof null === 'object'
f: undefined,//类型为undefined
g: function(){
console.log('函数')
},
h: new Date()
}
// 所以我们需要考虑我们的递归的方法
function deepClone(target){
// 分类型,基本,null,undefined,array,object,函数
if(Array.isArray(target)){
let result = []
for( let item of target){
item.push(deepClone(item))
}
return result
}else if