js深拷贝和浅拷贝

快乐打工仔 分类:实例代码

本章节介绍一下浅拷贝和深拷贝。

之所以出现深拷贝,也是由于要规避浅拷贝的缺陷,先来看一个浅拷贝的代码:

var original = {
  age: 3,
  webName: "犀牛前端部落", 
  antzoneObj: {
    address: "青岛市南区",
    target:"分享互助"
  }
};
var extend = function (result, source) {
  for (var key in source) {
    result[key] = source[key];
  }
  return result;
}
var newObj = extend({}, original);
newObj.antzoneObj.address = "青岛市北区";
console.log(newObj.antzoneObj.address);
console.log(original.antzoneObj.address);

从上面的代码可以看出,虽然我只想修改新对象的属性,但是原来对象的属性也被改变了。

因为result[key] = source[key]传递的知识对象的存储地址,{address: "青岛市南区",target:"分享互助"}没有真正被拷贝。

下面就来看一下深度拷贝:

var original = {
  age: 3,
  webName: "犀牛前端部落", 
  antzoneObj: {
    address: "青岛市南区",
    target:"分享互助"
  }
};
 
dom = {};
dom.is = function (obj, type) {
  var toString = Object.prototype.toString, undefined;
  return (type === "Null" && obj === null) ||
         (type === "Undefined" && obj === undefined) ||
         toString.call(obj).slice(8, -1) === type;
};
 
dom.deepCopy = function (result, source) {
  for (var key in source) {
    var copy = source[key];
    if (result === copy) continue;
    if (dom.is(copy, "Object")) {
      result[key] = arguments.callee(result[key] || {}, copy);
    }
    else if (dom.is(copy, "Array")) {
      result[key] = arguments.callee(result[key] || [], copy);
    } else {
      result[key] = copy;
    }
  }
  return result;
};
var newObj = dom.deepCopy({}, original);
newObj.antzoneObj.address = "青岛市北区";
console.log(newObj.antzoneObj.address);
console.log(original.antzoneObj.address);

上面的代码实现深度拷贝效果,下面介绍一下它的实现过程。

一.代码注释:

(1).var original = {  

  age: 3,

  webName: "犀牛前端部落", 

  antzoneObj: {

    address: "青岛市南区",

    target:"分享互助"

  }

},创建一个待拷贝的对象,内部嵌套有一个对象。

(2).dom = {},声明一个空对象,其实用作一个命名空间功能。

(3).dom.is = function (obj, type) {

  var toString = Object.prototype.toString, undefined;

  return (type === "Null" && obj === null) ||

         (type === "Undefined" && obj === undefined) ||

         toString.call(obj).slice(8, -1) === type;

},此方法的功能是准确判断数据的类型,第一个参数要判断的数据,第二个参数是类型,返回值是一个布尔值。

dom.deepCopy = function (result, source) {},实现深度拷贝功能,第一个参数目标对象,第二个参数是要被拷贝的对象。

(4).for (var key in source) {},遍历对象中的每一个属性。

(5).var copy = source[key],获取对应的属性值。

(6).if (result === copy) continue,防止是同一个对象产生死循环。

(7).if (dom.is(copy, "Object")) {

  result[key] = arguments.callee(result[key] || {}, copy);

},判断是否是一个对象。然后用递归的方式进行拷贝操作。

result[key] || {}的作用是,如果目标对象中没有同名属性,那么就使用一个空对象。

二.相关阅读:

(1).prototype可以参阅javascript prototype原型一章节。

(2).call()可以参阅js call()一章节。

(3).slice()可以参阅javascript slice()一章节。

回复

我来回复
  • 暂无回复内容