深拷贝与浅拷贝的区别于实现
- 深拷贝和浅拷贝是针对复杂数据类型说的,浅拷贝只拷贝一层,深拷贝是层层拷贝。
- 浅拷贝
浅拷贝将原对象的引用直接赋值给新对象,指向一致,所以彼此之间的操作会互相影响。
let a = b //指向一致,更改a的值会影响b
- 深拷贝
深拷贝复制变量值,对于非基本类型的变量,递归至基本类型后再复制。深拷贝后的对象与原来的对象完全隔离,互不影响。
使用JSON、递归函数进行深拷贝
使用扩展运算符深拷贝(适合用于内层结构都是基本类型的数组或对象)
let newArr = [...arr]
//如果arr结构里有复杂数据类型的话也是引用
Object.assign()合并对象
let newArr = Object.assign([],arr)
//返回一个新的数组,弊端跟扩展运算符拷贝一样
JSON进行深拷贝
let obj = JSON.parse(JSON.stringify(obj))
递归进行深拷贝
let arr = [1,2,{name:'user'}]
//在对象原型上添加一个深拷贝的方法
Object.prototype.copy = function(data){
//如果不是对象类型返回本身
if(typeof(data) !='object'){
return data
}else{
//如果是数组类型创建数组,否则创建对象
let deepData = data instanceof Array?[]:{}
//循环拷贝
for(let key in data){
//如果循环项是对象再次调用深拷贝方法进行深拷贝,否则直接赋值
if(typeof(data[key]) == 'object'){
deepData[key] = copy(data[key])
}else{
deepData[key] = data[key]
}
return deepData
}
}
let newArr = copy(arr)
原型及原型链
- proto
在js中每个对象都有一个内部属性proto,指向该对象的原型。 - prototype
在构造函数中有一个prototype属性,是构造函数才有的属性,也叫原型,包含所有实例共享的属性和方法,当创建实例时,该prototype就会作为实例对象的原型proto。 - 对象使用属性和方法时,首先会在当前proto中寻找,找到就是用,找不到就会去自己原型proto关联的prototype上寻找,找不到继续去prototype的proto关联的prototype上寻找,知道找到或报undefined
类型校检
-
typeof
一般用来判断基本类型
缺点:无法分辨对象类型
-
instanceof
判断对象类型,测试构造函数的prototype是否出现在被检测对象的原型链上
缺点:无法判断一个值到底属于数组还是普通对象
-
object.prototype.toString.call()
可以判断所有类型