zoukankan      html  css  js  c++  java
  • 实现一个深拷贝_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

  • 相关阅读:
    《算法竞赛进阶指南》0x12 队列 POJ2259 Team Queue
    《算法竞赛进阶指南》0x11栈 单调栈求矩形面积 POJ2559
    《算法竞赛进阶指南》0x11 栈 求解中缀表达式
    19.职责链模式(Chain of Responsibility Pattern)
    16.观察者模式(Observer Pattern)
    17.解释器模式(Interpreter Pattern)
    15. 迭代器模式(Iterator Pattern)
    14.命令模式(Command Pattern)
    12.代理模式(Proxy Pattern)
    13.模板方法(Template Method)
  • 原文地址:https://www.cnblogs.com/liuXiaoDi/p/13071559.html
Copyright © 2011-2022 走看看