• 实现一个深拷贝_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

  • 相关阅读:
    Android 使用 DownloadManager 管理系统下载任务的方法
    移动互联网时代:你的厕所文学是什么?
    zoj 3777 Problem Arrangement(壮压+背包)
    25个增强iOS应用程序性能的提示和技巧(0基础篇)
    Oracle 同义词
    Oracle loop、while、for循环
    Oracle 序列
    Oracle 视图
    Oracle 集合操作
    Oracle 伪列
  • 原文地址:https://www.cnblogs.com/liuXiaoDi/p/13071559.html
Copyright © 2020-2023  润新知