文章导航

JavaScript 深度拷贝和浅拷贝

2018-9-26 13:01| 作者: admin| 查看: 1249| 评论: 0|来自: 蚂蚁部落

拷贝是非常容易理解的概念,因为现实生活中拷贝操作实在太多。

JavaScript中的操作是将一个数据结构中的数据复制到另一个数据结构。

比如将一个对象中的属性拷贝到另一个对象中。

代码实例如下:

[JavaScript] 纯文本查看 复制代码运行代码
let target = {
    webName: "蚂蚁部落",
}
let webUrl = {
  url:"www.softwhy.com"
}
let web = Object.assign(target, webUrl);
console.log(web);
console.log(web==target);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201809/26/120433fft1rt8xqqh5bz3u.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

关于Object.assign方法的使用可以参阅Object.assign()方法一章节。

通过Object.assign方法将webUrl中的属性拷贝到target对象中。

特别说明:Object.assign方法进行浅拷贝。

JavaScript存在两种拷贝方式:

(1).浅拷贝。

(2).深度拷贝。

一.浅拷贝:

浅拷贝会将值类型数据拷贝到目标对象,但是引用类型数据只拷贝其引用地址,也就是数据的存储地址。

关于引用类型数据和值类型数据参阅JavaScript值类型和引用类型一章节。

上面代码中,源对象webUrl只包含值类型数据,无所谓浅拷贝或深度拷贝。

再来看一段代码实例:

[JavaScript] 纯文本查看 复制代码运行代码
let target = {
  webName: "蚂蚁部落"
}
let source = {
  url:"www.softwhy.com",
  num: {
    x: 1,
    y: 2
  }
}
var web = Object.assign(target, source);
console.log(web==target);
console.log(web);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201809/26/120542p0rujofoog6rao7l.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

代码分析如下:

(1).通过Object.assign方法将source对象的属性拷贝到target对象。

(2).source对象中,url属性值是值类型数据,num属性值是引用类型数据。

(3).值类型数据会实实在在拷贝到目标对象中,但是引用类型数据仅拷贝其引用地址,运行效果截图中,貌似num属性所指向的对象被拷贝到了target对象中,其实不然,由于Object.assign是浅拷贝,所以仅拷贝对象的引用地址。也就是说target对象和source对象中的num属性指向同一个对象。

代码证实如下:

[JavaScript] 纯文本查看 复制代码运行代码
let target = {
  webName: "蚂蚁部落"
}
let source = {
  url:"www.softwhy.com",
  num: {
    x: 1,
    y: 2
  }
}
var web = Object.assign(target, source);
source.num.x=10;
console.log(target.num.x);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201809/26/120627cc38uozpw28c83c2.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

上述代码中,修改source对象num属性所指向对象的x属性值,但是target对象的num属性所指向对象的x属性值同步发生了改变,由此可见,浅拷贝仅仅是拷贝引用类型数据的地址。

二.深度拷贝:

与浅拷贝不同,深度拷贝不但将值类型数据拷贝到目标对象,也会将引用类型数据拷贝到目标对象。

代码实例如下:

[JavaScript] 纯文本查看 复制代码
let source = {
  url:"www.softwhy.com",
  num: {
    x: 1,
    y: 2
  }
}

深度拷贝会将url和num属性拷贝到目标对象,与浅拷贝不同的是,深度拷贝会将num属性所指向的对象拷贝一份到目标对象,而不是仅仅拷贝对象引用地址。

代码实例如下:

[JavaScript] 纯文本查看 复制代码运行代码
let target = {
  webName: "蚂蚁部落"
}
let source = {
  url:"www.softwhy.com",
  num: {
    x: 1,
    y: 2
  }
}
function deepCopy(target, source) {
  for (var prop in source) {
    if (typeof source[prop] === 'object') {
      target[prop] = (source[prop].constructor === Array) ? [] : {};
     deepCopy(target[prop], source[prop]);
    } 
     else {
      target[prop] = source[prop];
    }
  }
  return target; 
}
console.log(deepCopy(target, source));
source.num.x=10;
console.log(target.num.x);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201809/26/120720gi7i9hj071j1qy0j.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

可以看到,修改source对象的num所指向对象的属性值,并不会对target对象产生影响。


鲜花

握手

雷人

路过

鸡蛋

最新评论

返回顶部