实现一个深拷贝_undefined_RegExp_function_详细注释
前言
实现一个深拷贝:可以复制undefined,function.能够保证RegExp复制并且类型不变.
可以参考本文来实现如Date()的深拷贝
知识点
getOwnPropertyNames
getOwnPropertyNames返回指定对象内部的所有属性名组成的数组
getOwnPropertyDescriptor
getOwnPropertyDescriptor返回某个对象属性的描述对象,举个例子看描述对象的内容
var obj2={ g:/^[a-z]{1,2}$/gi } let desc=Object.getOwnPropertyDescriptor(obj2,'g') console.log('desc',desc)

value的具体打印,可以看到描述对象的value上可以访问到原型对象:desc.value.constructor指向了RegExp.在拷贝正则的时候,我们就可以利用new desc.value.constructor生成一个新正则

Object.defineProperty
在对象上定义新属性和属性值
实现
<!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>
<script>
function deepClone(newObj,source){
//getOwnPropertyNames返回指定对象内部的所有属性名组成的数组
var names=Object.getOwnPropertyNames(source);
for(let i=0;i<names.length;i++){
//getOwnPropertyDescriptor返回某个对象属性的描述对象
var desc=Object.getOwnPropertyDescriptor(source,names[i])
console.log('desc',desc)
//当前属性值是对象时
if(typeof desc.value==="object" && desc.value!==null){
var obj;
//desc.value.constructor指向了原型,比如RegExp
switch(desc.value.constructor){
case RegExp:
//等于 new RegExp()
obj=new desc.value.constructor(desc.value.source,desc.value.flags);
break;
case Function:
obj=new desc.value.constructor(desc.value.source,desc.value.flags);
break;
default:
obj=new desc.value.constructor()
}
deepClone(obj,desc.value);
Object.defineProperty(newObj,names[i],{
value:obj,
enumerable:desc.enumerable,
writable:desc.writable,
configurable:desc.configurable
});
}else{
Object.defineProperty(newObj,names[i],desc);
}
}
return newObj;
}
var obj={
a:1,
b:"a",
d:{
e:undefined,
f:[1,2,3],
g:/^[a-z]{1,2}$/gi
},
h:function(){
console.log(11)
}
}
var obj1=deepClone({},obj);
</script>
</body>
</html>
执行代码,查看打印结果,确定是否完成深拷贝
1.正则的desc描述符
console.log('desc',desc)

2.深拷贝后的obj1,可以看出和obj完全相同
console.log('深拷贝后的obj1',obj1)

3.修改obj1并查看obj是否被影响.可以看到obj没有被影响,我们的深拷贝成功
obj1.d={'di':'didi'}
console.log('修改后obj1',obj1);
console.log('obj1修改后的obj',obj);

4.执行obj1拷贝的方法
obj1.h()
打印出11

开源中国博客地址:https://my.oschina.net/u/2998098/blog/1540520

浙公网安备 33010602011771号