赋值

  • 基本类型: 传值,在栈内存中的数据发生数据变化的时候,系统会自动为新的变量分配一个新的之值在栈内存中,两个变量相互独立,互不影响的
  • 引用类型: 传址,只改变指针的指向,指向同一个对象,两个变量相互干扰
//基本数据类型赋值
var a = 10;
var b = a;
a++ ;
console.log(a); // 11
console.log(b); // 10 //引用数据类型赋值
let a = { name: '11' }
let b = a
b.name = '22'
console.log(a.name) // 22
console.log(b.name) // 22

浅拷贝

  • 对于基本类型,浅拷贝是对值的复制,拷贝前后对象的基本数据类型互不影响
  • 对于引用类型来说,浅拷贝是对对象地址的复制, 也就是拷贝的结果是两个对象指向同一个地址,所以如果其中一个对象改变了这个地址,就会影响到另一个对象

注意:浅拷贝只复制一层对象的属性

实现浅拷贝方法

方法一:Object.assign

语法:Object.assign(target, ...sources)   
ES6中拷贝对象的方法,接受的第一个参数target是拷贝后的对象,剩下的参数是要拷贝的对象sources(可以是多个)

例1:

let target = {};
let source = {a:'11',b:{name:'duoduo'}};
Object.assign(target ,source);
console.log(target); // { a: '11', b: { name: 'duoduo' } }

例2:

let target = {};
let source = {a:'11',b:{name:'duoduo'}}; Object.assign(target ,source); source.a = '22';
source.b.name = 'nana' console.log(source); // { a: '22', b: { name: 'nana' } }
console.log(target); // { a: '11', b: { name: 'nana' } }

Object.assign注意事项

  1. 只拷贝源对象的自身属性(不拷贝继承属性)
  2. 它不会拷贝对象不可枚举的属性
  3. undefined和null无法转成对象,它们不能作为Object.assign参数,但是可以作为源对象
  4. 属性名为Symbol 值的属性,可以被Object.assign拷贝。

方法二:Array.prototype.slice

实现原数组的浅拷贝

var a = [ 1, 3, 5, { x: 1 } ];
var b = Array.prototype.slice.call(a);
b[0] = 2;
console.log(a); // [ 1, 3, 5, { x: 1 } ];
console.log(b); // [ 2, 3, 5, { x: 1 } ]; // 从输出结果可以看出,浅拷贝后,数组a[0]并不会随着b[0]改变而改变
// 说明a和b在栈内存中引用地址并不相同。
var a = [ 1, 3, 5, { x: 1 } ];
var b = Array.prototype.slice.call(a);
b[3].x = 2;
console.log(a); // [ 1, 3, 5, { x: 2 } ];
console.log(b); // [ 1, 3, 5, { x: 2 } ];
// 从输出结果可以看出,浅拷贝后,数组中对象的属性会根据修改而改变
// 说明浅拷贝的时候拷贝的已存在对象的对象的属性引用。

方法三:Array.prototype.concat

let array = [{a: 1}, {b: 2}];
let array1 = [{c: 3},{d: 4}];
let array2=array.concat(array1);
array1[0].c=123;
console.log(array2);// [ { a: 1 }, { b: 2 }, { c: 123 }, { d: 4 } ]
console.log(array1);// [ { c: 123 }, { d: 4 } ]

方法四:...扩展运算符

语法:var cloneObj = { ...obj };

var a = [ 1, 3, 5, { x: 1 } ];
var b = {...a};
b[0] = 2;
console.log(a); // [ 1, 3, 5, { x: 1 } ];
console.log(b); // [ 2, 3, 5, { x: 1 } ]; // 从输出结果可以看出,浅拷贝后,数组a[0]并不会随着b[0]改变而改变
// 说明a和b在栈内存中引用地址并不相同。
var a = [ 1, 3, 5, { x: 1 } ];
var b = {...a};
b[3].x = 2;
console.log(a); // [ 1, 3, 5, { x: 2 } ];
console.log(b); // [ 1, 3, 5, { x: 2 } ];
// 从输出结果可以看出,浅拷贝后,数组中对象的属性会根据修改而改变
// 说明浅拷贝的时候拷贝的已存在对象的对象的属性引用。

其他方法:

//浅拷贝实现
var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
function shallowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
shallowObj.arr[1] = 5;
obj.arr[1] // = 5

深拷贝

深拷贝开辟一个新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性

注意:深拷贝对对象中的子对象进行递归拷贝,拷贝前后两个对象互不影响

实现方法:

方法一:JSON.parse(JSON.stringify())

  • JSON.stringify()是前端开发过程中比较常用的深拷贝方式。
  • 原理是把一个对象序列化成为一个JSON字符串,将对象的内容转换成字符串的形式再保存在磁盘上,再用JSON.parse()反序列化将JSON字符串变成一个新的对象
let arr = [1, 2, {name: ' duoduo'}];
let newarr = JSON.parse(JSON.stringify(arr)); newarr[2].name = 'nana'; console.log(newarr); // [ 1, 2, { username: 'nana' } ]
console.log(arr); // [ 1, 2, { username: 'duoduo' } ]

JSON.stringify()实现深拷贝注意点

  1. 拷贝的对象的值中如果有函数,undefined,symbol则经过JSON.stringify()序列化后的JSON字符串中这个键值对会消失
  2. 无法拷贝不可枚举的属性,无法拷贝对象的原型链
  3. 拷贝Date引用类型会变成字符串
  4. 拷贝RegExp引用类型会变成空对象
  5. 对象中含有NaN、Infinity和-Infinity,则序列化的结果会变成null
  6. 无法拷贝对象的循环应用(即obj[key] = obj)

方法二:jquery 的 $.extend

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

赋值、深拷贝、浅拷贝

浅拷贝和深拷贝区别
浅拷贝只复制一层对象的属性,而深拷贝则递归复制了所有层级

**

JS的赋值与深浅拷贝实例的更多相关文章

  1. python直接赋值、深浅拷贝实例剖析

    根据数据类型分为两部分进行剖析: int.str类型      list.tuple.dict类型等 1.  int.str类型 [int类型实例] >>> import copy ...

  2. JS对象和数组深浅拷贝总结②

    在实际开发中遇到过太多次深拷贝浅拷贝的问题.总结一下~ JS数据存储和深浅拷贝实际运用① 这是之前写过的一篇文章,解决浅拷贝深拷贝的问题只说了一种方法,今天来补充一下. 介绍深拷贝和浅拷贝都在上一篇文 ...

  3. python——赋值与深浅拷贝

    初学编程的小伙伴都会对于深浅拷贝的用法有些疑问,今天我们就结合python变量存储的特性从内存的角度来谈一谈赋值和深浅拷贝~~~ 预备知识一——python的变量及其存储 在详细的了解python中赋 ...

  4. 【python】变量的赋值、深浅拷贝

    python——赋值与深浅拷贝 https://www.cnblogs.com/Eva-J/p/5534037.html 啥都不说,看这个博主的文章!

  5. python基础知识5——赋值与深浅拷贝——整数和字符串,列表元组字典

    深浅copy 一.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. 1 import copy 2 # ######### 数字.字符串 #### ...

  6. python--关于赋值与深浅拷贝的认识

    作为一个自学python的小白,平时用到深浅拷贝的机会很少,因此对其也是一知半解.但是,作为一个立志成为后端工程狮的男人,眼里揉不了沙子,于是专门花时间补了补课,在此记录一下学习心得.    在讲深浅 ...

  7. python中的“赋值与深浅拷贝”

    Python中,赋值与拷贝(深/浅拷贝)之间是有差异的,这主要源于数据在内存中的存放问题,本文将对此加以探讨. 1 赋值(添加名字) 赋值不会改变内存中数据存放状态,比如在内存中存在一个名为data的 ...

  8. python语法基础-基础-赋值与深浅拷贝

    ##################################### 预备知识一——python的变量及其存储 在详细的了解python中赋值.copy和deepcopy之前,我们还是要花一点时 ...

  9. python3 列表的赋值和深浅拷贝

    '''列表赋值:不会创建新对象两个列表的内存地址一样'''# lst1 = ["apple", "banana", ["blueberry" ...

随机推荐

  1. Vue开发者必会的基础知识盘点

    你会Vue吗,你看以下知识点你掌握了多少?实际工作中是否运用的得心应手?如果是,那么恭喜你! Vue中的数据和DOM已经被关联起来,所有的东西都是响应式的.注意我们不再和HTML直接交互.一个Vue应 ...

  2. 3.新手建站教程系列之认识WordPress和第一篇文章

    上一期咱已经把本地环境和wp网站给搭建出来了,接下来就是来认识这个程序了.进入网站后台,地址为你的网址/wp-admin 后台名字叫做仪表盘,首页是一个信息合集区域,上面会显示有多少文章,多少页面以及 ...

  3. Java 并发实践 — ConcurrentHashMap 与 CAS

    转载 http://www.importnew.com/26035.html 最近在做接口限流时涉及到了一个有意思问题,牵扯出了关于concurrentHashMap的一些用法,以及CAS的一些概念. ...

  4. AI大厂算法测试心得:人脸识别关键指标有哪些?

    仅仅在几年前,程序员要开发一款人脸识别应用,就必须精通算法的编写.但现在,随着成熟算法的对外开放,越来越多开发者只需专注于开发垂直行业的产品即可. 由调查机构发布的<中国AI产业地图研究> ...

  5. MacOS下SpringBoot基础学习

    学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"springboot"获取视频和教程资料! b站在线视 ...

  6. Python os.read() 方法

    概述 os.read() 方法用于从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串.高佣联盟 www.cgewang.com ...

  7. 错误记录:MIME type may not contain reserved characters

    最近遇到个问题,随手记录一下! 新做了一个项目,要通过HTTP请求发送ZIP文件到OSS平台,但上传过程中,总是出现下面错误提示: 初步判定,应该是包冲突原因!于是,分析MIME-TYPE获取源码发现 ...

  8. Maven打包方式

    转自:https://blog.csdn.net/qq_26597927/article/details/80170073 Maven打包三种方法(推荐第三种) 2018年05月02日 18:30:2 ...

  9. explain关键字使用解释

    原文: 58沈剑 架构师之路  https://mp.weixin.qq.com/s/oWNrLHwqM-0ObuYbuGj98A <数据库允许空值,往往是悲剧的开始>一文通过explai ...

  10. 移动物体监控系统-sprint4嵌入式web服务器开发

    一.BOA嵌入式服务器的移植 step1:下载BOA服务器并解压,进入boa下面的src目录,执行./configure生成必须的配置文件以及Makefile step2:修改Makefile文件 c ...