最新文章专题视频专题关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

什么是js深拷贝和浅拷贝及其实现方式

来源:懂视网 责编:小采 时间:2020-11-27 15:27:36
文档

什么是js深拷贝和浅拷贝及其实现方式

什么是js深拷贝和浅拷贝及其实现方式:今天来给大家说一下JS的js深拷贝和浅拷贝,它们有什么区别,有什么作用呢?下面给大家举例说明一下。var m = { a: 10, b: 20 }var n = m;n.a = 15;// 这时m.a的值是多少m.a会输出15,因为这是浅拷贝,n和m指向的是同一个堆,对象复制只是复制的对象的引用。
推荐度:
导读什么是js深拷贝和浅拷贝及其实现方式:今天来给大家说一下JS的js深拷贝和浅拷贝,它们有什么区别,有什么作用呢?下面给大家举例说明一下。var m = { a: 10, b: 20 }var n = m;n.a = 15;// 这时m.a的值是多少m.a会输出15,因为这是浅拷贝,n和m指向的是同一个堆,对象复制只是复制的对象的引用。

今天来给大家说一下JS的js深拷贝和浅拷贝,它们有什么区别,有什么作用呢?下面给大家举例说明一下。

var m = { a: 10, b: 20 }var n = m;n.a = 15;// 这时m.a的值是多少

m.a会输出15,因为这是浅拷贝,n和m指向的是同一个堆,对象复制只是复制的对象的引用。

深拷贝

深拷贝和上面浅拷贝不同,就是彻底copy一个对象,而不是copy对象的引用,例如,还是之前的例子,我们这么写:

var m = { a: 10, b: 20 }var n = {a:m.a,b:m.b};n.a = 15;

这次,我们再来输出m.a ,发现m.a的值还是10,并没有改变,m对象和n对象是虽然所有的值都是一样的,但是在堆里面,对应的不是同一个了,这个就是深拷贝。

深拷贝和浅拷贝

深拷贝和浅拷贝的示意图大致如下:

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

浅拷贝的实现方式

1、可以通过简单的赋值实现

类似上面的例子,当然,我们也可以封装一个简单的函数,如下:

function simpleClone(initalObj) { 
 var obj = {}; 
 for ( var i in initalObj) {
 obj[i] = initalObj[i];
 } 
 return obj;
 }
 var obj = {
 a: "hello",
 b:{
  a: "world",
  b: 21
 },
 c:["Bob", "Tom", "Jenny"],
 d:function() {
  alert("hello world");
 }
 }
 var cloneObj = simpleClone(obj); 
 console.log(cloneObj.b); 
 console.log(cloneObj.c);
 console.log(cloneObj.d);
 cloneObj.b.a = "changed";
 cloneObj.c = [1, 2, 3];
 cloneObj.d = function() { alert("changed"); };
 console.log(obj.b);
 console.log(obj.c);
 console.log(obj.d);

2、Object.assign()实现

Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是 Object.assign() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

var obj = { a: {a: "hello", b: 21} };var initalObj = Object.assign({}, obj);initalObj.a.a = "changed";console.log(obj.a.a); // "changed"

注意:当object只有一层的时候,是深拷贝,例如如下:

var obj1 = { a: 10, b: 20, c: 30 };var obj2 = Object.assign({}, obj1);obj2.b = 100;console.log(obj1);// { a: 10, b: 20, c: 30 } <-- 沒被改到console.log(obj2);// { a: 10, b: 100, c: 30 }

深拷贝的实现方式

1、方法一还是手动复制

和上面的举例一样,手动复制可以实现深拷贝。

2、对象只有一层的话可以使用上面的:Object.assign()函数

3、转成 JSON 再转回来

var obj1 = { body: { a: 10 } };var obj2 = JSON.parse(JSON.stringify(obj1));obj2.body.a = 20;console.log(obj1);// { body: { a: 10 } } <-- 沒被改到console.log(obj2);// { body: { a: 20 } }console.log(obj1 === obj2);// falseconsole.log(obj1.body === obj2.body);// false

用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。

可以封装如下函数

var cloneObj = function(obj){
 var str, newobj = obj.constructor === Array ? [] : {};
 if(typeof obj !== 'object'){
 return;
 } else if(window.JSON){
 str = JSON.stringify(obj), //系列化对象
 newobj = JSON.parse(str); //还原
 } else {
 for(var i in obj){
  newobj[i] = typeof obj[i] === 'object' ? 
  cloneObj(obj[i]) : obj[i]; 
 }
 }
 return newobj;};

4、递归拷贝

function deepClone(initalObj, finalObj) { 
 var obj = finalObj || {}; 
 for (var i in initalObj) { 
 var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
 if(prop === obj) {  
 continue;
 } 
 if (typeof prop === 'object') {
 obj[i] = (prop.constructor === Array) ? [] : {};  
 arguments.callee(prop, obj[i]);
 } else {
 obj[i] = prop;
 }
 } 
 return obj;}var str = {};var obj = { a: {a: "hello", b: 21} };deepClone(obj, str);console.log(str.a);

5、使用Object.create()方法

直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。

function deepClone(initalObj, finalObj) { 
 var obj = finalObj || {}; 
 for (var i in initalObj) { 
 var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
 if(prop === obj) {  
 continue;
 } 
 if (typeof prop === 'object') {
 obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
 } else {
 obj[i] = prop;
 }
 } 
 return obj;}

6、jquery

jquery 有提供一个$.extend可以用来做 Deep Copy。

var $ = require('jquery');var obj1 = {
 a: 1,
 b: { f: { g: 1 } },
 c: [1, 2, 3]};var obj2 = $.extend(true, {}, obj1);console.log(obj1.b.f === obj2.b.f);// false

7、lodash

另外一个很热门的函数库lodash,也有提供_.cloneDeep用来做 Deep Copy。

var _ = require('lodash');var obj1 = {
 a: 1,
 b: { f: { g: 1 } },
 c: [1, 2, 3]};var obj2 = _.cloneDeep(obj1);console.log(obj1.b.f === obj2.b.f);// false

这个性能还不错,使用起来也很简单。

相信看了这些案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

相关阅读:

HTML里的最后一行文字显示不全怎么处理

怎样用css3做出图标效果

CSS的编码怎么转换

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:0731-84117792 E-MAIL:11247931@qq.com

文档

什么是js深拷贝和浅拷贝及其实现方式

什么是js深拷贝和浅拷贝及其实现方式:今天来给大家说一下JS的js深拷贝和浅拷贝,它们有什么区别,有什么作用呢?下面给大家举例说明一下。var m = { a: 10, b: 20 }var n = m;n.a = 15;// 这时m.a的值是多少m.a会输出15,因为这是浅拷贝,n和m指向的是同一个堆,对象复制只是复制的对象的引用。
推荐度:
标签: 方法 实现 js
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top