实现一个深拷贝_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://www.cnblogs.com/liuXiaoDi/p/13071559.html