typeof运算符:
- 识别所有值类型
- 识别函数
- 判断是否是引用类型(不可再细分)
深拷贝
代码演示:
第一步:准备环境
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p>一段文字</p>
<script src="./deepClone.js"></script>
</body>
</html>
deepClone.js
console.log('deepClone');
第二步:这里不做深拷贝先,浅拷贝
//目的:拷贝一个东西(对象/引用类型)
const obj1 = {
age: 20,
name: 'xxx',
address: {
city: 'beijing'
},
arr: ['a', 'b', 'c']
}
//这里是浅拷贝
const obj2 = obj1
obj2.address.city = 'shanghai'
console.log(obj1.address.city); //shanghai 2修改后1也随之修改 符合引用类型的拷贝规则:浅拷贝
接下来要做一个深拷贝,就是说让obj2=obj1的时候,obj2改值后(obj2.address.city=’shanghai’),obj1它不会变。这就是深拷贝。
核心代码演示:
//目的:拷贝一个东西(对象/引用类型)
const obj1 = {
age: 20,
name: 'xxx',
address: {
city: 'beijing'
},
arr: ['a', 'b', 'c']
}
//深拷贝,调用deepClone(),传入obj1,最终返回一个值到obj2,这就是深拷贝的过程,不能直接赋值
const obj2 = deepClone(obj1);
obj2.address.city = 'shanghai'
console.log(obj1.address.city);
/**深拷贝
* @param {Object} obj 要拷贝的对象
* 怎么写深拷贝?
*/
function deepClone(obj = {}) {
//怎么写深拷贝?
//1.首先我们的obj是一个对象或数组,但是如果不是呢,则需要判断
if(typeof obj != 'object' || obj == null) {
//obj 是 null,或者不是对象和数组,直接返回,不做深拷贝
return obj
}
//2.初始化返回结果 分清数组还是对象
let result
//先判断下obj 是否是 数组 还是 对象
if(obj instanceof Array) {
//传入的值如果是数组,返回数组格式
result = []
}else{
//传入的值如果不是数组,返回对象格式
result = {}
}
//中间处理--无论是对象或数组都可以用for in 遍历
for(let key in obj) {
//hasOwnProperty:用于检查给定的属性在当前对象实例中(而不是在实例的原型中)
//保证key不是原型的属性
if(obj.hasOwnProperty(key)) {
//递归调用(重点) -->防止深层次的对象/数组都能拷贝出来,一层一层完成深拷贝
result[key] = deepClone(obj[key])
}
}
//返回结果
return result
}
效果:
加例子检查:
obj2.address.city = 'shanghai'
obj2.arr[0] = 'a1';
console.log(obj1.address.city);
console.log(obj1.arr[0]);