阅读 105

js深拷贝对象

js深拷贝对象

浅拷贝和深拷贝的区别
浅拷贝:只拷贝对象的基础属性值,对属性值为对象或数组的属性则拷贝指针。
深拷贝:拷贝对象的所有属性作为一个全新的对象。拷贝前后的对象互不影响。

字面量属性浅拷贝

    var a = {name:"test",children:{name:"test1"}}
    //浅拷贝
    var b = {
        name:a.name,
        children:a.children
    }
    a.name = "字面量属性拷贝"
    a.children.name = "浅拷贝"
    console.log(a)//Object {name: "字面量属性拷贝", children: Object{name:"浅拷贝"}}
    console.log(b)//Object {name: "test", children: Object{name:"浅拷贝"}}
复制代码

可以看出浅拷贝只拷贝了对象的基础属性值,对对象或数组的属性值则是只是拷贝了引用。所以修改a.name的时候,由于name的属性值为字符串所以直接拷贝了,a的修改不影响b。当修改a.children属性的时候,由于该属性值是个对象,所以b只拷贝了引用,故b.children也变化了

字面量属性深拷贝

var a = {name:"test",children:{name:"test1"}}
//深拷贝
var b = {
    name:a.name,
    children:{name:a.children.name}
}
a.name = "字面量属性拷贝"
a.children.name = "浅拷贝"
console.log(a)//Object {name: "字面量属性拷贝", children: Object{name:"浅拷贝"}}
console.log(b)//Object {name: "test", children: Object{name:"test1"}}
复制代码

深拷贝是对浅拷贝的进一步解析,直到所有的属性都为基础属性值为止,所以深拷贝的对象是完全独立的一个新对象。

深拷贝公共方法封装

//返回传递给他的任意对象的类
const isClass = (o) => {
  if (o === null) return "Null";
  if (o === undefined) return "Undefined";
  return Object.prototype.toString.call(o).slice(8, -1);
}


//使用递归深度克隆
const deepClone = (obj) => {
  if (!obj) { return null }
  let result, oClass = isClass(obj);
  //确定result的类型
  if (oClass === "Object") {
    result = {};
  } else if (oClass === "Array") {
    result = [];
  } else {
    return obj;
  }

  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      let copy = obj[key];
      if (isClass(copy) == "Object") {
        result[key] = deepClone(copy);//递归调用
      } else if (isClass(copy) == "Array") {
        result[key] = deepClone(copy);
      } else {
        result[key] = obj[key];
      }
    }
  }
  return result;
}
复制代码

Object.assign() 特别注意:ES6提供了一个Object.assign()方法用于拷贝和合并对象,但是该方法也只是一个浅拷贝方法,使用时请慎重。

文章分类
前端
文章标签