深拷贝:针对Date、DOM、RegExp、Object、Array类型的深拷贝

2,034 阅读1分钟

手写深拷贝

JavaScript一共有几种数据类型,这应该是面试官最喜欢问的了吧!大概有以下7种

  • Number
  • String
  • Boolean
  • Null
  • Undefined
  • Symbol
  • Object 嗯!!现在应该有八种,以后面试就要回答八种了吧! BigInt

BigInt类型是 JavaScript 中的一个基础的数值类型,可以用任意精度表示整数。使用 BigInt,您可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。BigInt 是通过在整数末尾附加 或调用构造函数来创建的。

普通的深拷贝都是针对object、array之类的拷贝

如果遇到对象中出现了一些Date类型、正则类型的对象在利用普通的深拷贝的时候得出的结果可能跟我们预想的有点出入

即使用上JSON.Parse(JSON.stringify(object))
也没用,这个时候除了利用一些插件自带的拷贝方法也可以尝试着自己手写一个。

可能我囊括的类型不是很全,但日常使用应该是没有太大问题,希望指正

        let a = {
            "apple"'apple tree',
            "orange"/g/i,
            "lemon": ["book"new Date(), /^[0-9]*$/document.head],
            'Avocado'new Date(),
            'pear'document.body
        }

先看看上面这个源对象,是不是比普通的对象内容要复杂一点,如果是你你要怎么对他进行深拷贝呢?

直接上代码:

        function deepClone(obj) {
            // 校验对象类型
            if(typeof obj !== 'object' || obj === null) throw new Error(arguments[0] + ' is not a object');
            let newObj = (obj instanceof Array) ? [] : {};
            for (const key in obj) {
                // 访问对象自身属性
                if (Object.hasOwnProperty.call(obj, key)) {
                    const element = obj[key]; //存放原对象的值
                    if(!newObj[key]) {
                        if(element instanceof Date) {
                            // 日期类型
                            let time = new Date(element.getTime()); // 与被拷贝时间达到一致
                            newObj[key] = time;
                        }else if(element instanceof RegExp) {
                            // 正则类型
                            JSON.stringify
                            newObj[key] = new RegExp(element);
                        } else if((typeof element === 'object' && element !== null) && element.nodeType === 1) {
                            //DOM元素节点 { nodeType }
                            // 元素类型 --> 节点类型
                            // 元素element --> 1
                            // 属性attr --> 2
                            // 文本text -->  3
                            // 注释comments --> 8
                            // 文档document --> 9
                            let dom = document.getElementsByTagName(element.nodeName)[0];
                            newObj[key] = dom;
                        } else {
                            newObj[key] = typeof element === 'object' && element !== null  ? deepClone(element) : element;
                        }
                    }
                }
            }
            return newObj;
        }
        let a = {
            "apple": 'apple tree',
            "orange": /g/i,
            "lemon": ["book", new Date(), /^[0-9]*$/, document.head],
            'Avocado': new Date(),
            'pear': document.body,
            b: null,
            c: undefined,
            e: Symbol()
        }
        let b = deepClone(a);
        console.log(a,b);