递归实现深拷贝

130 阅读1分钟
      let oldobj = {
        name: "John",
        age: 30,
        isMarried: false,
        birds: true,
        cars: ["Ford", "Audi", "BMW"],
        friend: {
          name: "小夏",
        },
      };
function deepClone(obj = {}) {
        //判断传参是否是对象或者为空值
        if (typeof obj !== "object" || obj == null) {
          return obj;
        }
        let result;
        //判断数组则用数组类型
        //这里判断有多种方法
        if (obj.constructor == Array) {
          result = [];
        } else {
          result = {};
        }
        for (let key in obj) {
        //hasOwnProperty表示是否有自己的属性。
        //这个方法会查找一个对象是否有某个属性,但是不会去查找它的原型链
        只拷贝这个对象本身的属性,这个对象原型上的属性不去拷贝,所以加判断
          if (obj.hasOwnProperty(key)) {
            result[key] = deepClone(obj[key]);
          }
        }
        return result;
      }

tips:判断数组的方法 1、instanceof

instanceof的内部机制是通过判断对象的原型链中是不是能找到类型的 prototype,

let obj = ['1','2','3']
obj instanceof Array   //会返回true

大部分情况都可以用instanceof判断是否是数组,但是在判断一个变量是对象或非对象时,会存在坑,因为数组也是对象。

2、constructor

3、isArray()

4、Array.prototype.toString.call()


let newobj = deepClone1(oldobj);
      newobj.name = "Tom";
      newobj.friend.name = "小亮";
      console.log("oldobj", oldobj);
      console.log("newobj", newobj);

image.png

这里我们修改了深拷贝过来的新对象里面的属性值,可以看到旧对象的值并没有被改变。