js 浅拷贝直接赋值_JS中的赋值、浅拷贝与深拷贝
作者:奚杰
拷贝是写代码中经常使用的方法。浅拷贝与深拷贝是指拷贝的两种情况。本文将深入探究JS的赋值、浅拷贝与深拷贝。
数据类型
在探究深拷贝与浅拷贝之前,我们先梳理一下JS的数据类型。在JavaScript中,数据类型有两大类。一类是基本数据类型,一类是引用数据类型。
基本数据类型有五种:number、string、boolean、null、undefined。基本数据类型存放在栈中。存放在栈中的数据具有数据大小确定,内存空间大小可以分配、直接按值存放的特点。所以存放在栈中的数据可以直接访问。在JavaScript中,基本的数据类型值是不可更改的。可能这一点不符合我们平常的使用认知。我们在修改字符串或其他基本数据类型变量时,实际上是返回了一个新的值,而不是【改变】原始值。
而对于引用数据类型,是存放在堆内存中。引用数据类型的变量并不是存放的实际值,而是一个存放在栈内存的指针,该指针指向堆内存中的某个地址。每个数据所占的空间大小不一致,需要根据情况进行特定的分配。与基本数据类型不同,引用类型的值是可以改变的。
赋值:传值与传址
有了对JavaScript数据类型的一定了解后,我们接下来看看不同类型的数据类型在赋值时的区别。
对于基本数据类型来说,当我们进行赋值操作(=)时,实际上是在内存中新开一段栈内存,然后再将值赋值到新的栈中。
举个例子:
let a = 1
let b = a
a = 5
console.log(a) // 5
console.log(b) // 1
对于上述语句,b变量虽然是a变量的复制,但与a变量是独立互不影响的变量。
而对于引用数据类型来说,在进行赋值操作时,实际上是把变量的地址传给了另一个变量,所以称为传址。传址之后,两个变量就指向同一个地址,两者的操作是互有影响的。
例:
let a = { age: 12 }
let b = aa.age = 13
console.log(a.age) // 13
console.log(b.age) // 13b.age = 14
console.log(a.age) // 14
console.log(b.age) // 14
浅拷贝与深拷贝
只有当拷贝引用数据类型时,拷贝才存在浅拷贝与深拷贝之分。
浅拷贝
浅拷贝就是指创建一个新对象,该对象拥有原始对象第一层属性的精确拷贝。即:如果原始对象的属性是基本类型数据,则拷贝的就是基本数据类型的值;如果原始对象的属性是引用类型,则拷贝的是内存地址。当原始对象的引用类型属性发生改变时,拷贝对象的对应属性值也会发生变化。这里需要强调一下,浅拷贝与赋值是有所区别的,赋值时与原数据指向同一对象,而浅拷贝则指向了不同对象。
让我们来实现一个浅拷贝方法。
function shallowCopy(src) {const dist = {}for (let prop in src) {if (src.hasOwnProperty(prop)) {dist[prop] = src[prop]}}return dist
}
深拷贝
浅拷贝是对原始对象第一层属性的精确拷贝,而深拷贝则是对原始对象所有层级属性的递归精确拷贝。
深拷贝的实现
JSON
function deepCopy (src) {let temp = JSON.stringify(src)let dist = JSON.parse(temp)return dist
}
递归实现
function deepCopy (src) {if (typeof src !== 'object') {return src}if (src == null) {return null}let dist = Array.isArray(src) ? [] : {}if (src && typeof src === "object") {for (let prop in src) {if (src.hasOwnProperty(prop)) {// 如果子属性为引用数据类型,递归复制if (src[prop] && typeof src[prop] === "object") {dist[prop] = deepCopy(src[prop])} else {// 如果是基本数据类型,只是简单的复制dist[prop] = src[prop]}}}}return dist
}
js 浅拷贝直接赋值_JS中的赋值、浅拷贝与深拷贝相关推荐
- python中怎么赋值,python中的赋值操作
参考:https://www.cnblogs.com/andywenzhi/p/7453374.html?tdsourcetag=s_pcqq_aiomsg(写的蛮好) python中的赋值操作&qu ...
- php给textarea赋值,html中textarea赋值与取值问题详细讲解
html中textarea赋值与取值问题详细讲解2017-10-17 21:49 许多小伙伴在编程的时候,容易搞错一个问题,就是对textarea赋值. 因为第一感觉就是textarea和input一 ...
- js 浅拷贝直接赋值_JS中实现浅拷贝和深拷贝的代码详解
(一)JS中基本类型和引用类型 JavaScript的变量中包含两种类型的值:基本类型值 和 引用类型值,在内存中的表现形式在于:前者是存储在栈中的一些简单的数据段,后者则是保存在堆内存中的一个对象. ...
- js 多个定时器_JS中的同步/异步编程
1. 进程(process)/线程(thread) 进程process: 电脑端安装很多的应用软件,每当运行一个应用程序,相当于开辟一个进程(而对于浏览器来说,每新建一个页卡访问一个页面,都是新开辟一 ...
- python中有哪些赋值_python中的赋值,什么时候是传值什么时候是传址?
参数的传递是通过自动将对象赋值给本地变量名来实现的.在函数运行时,函数头部的参数名是一个新的.本地的变量名,这个变量名是在函数的本地作用域内存在.参数的传递本质上就是python赋值的另一个实例而已. ...
- python 逗号赋值_python中字符串赋值 逗号_四、python字符串
4.1.字符串基本操作 所有标准序列操作(索引.切片.乘法.成员资格检查.长度.最大值.最小值)都适用于字符串. 字符串是不可变的,因此所有的元素赋值和切片赋值都是非法的. 4.2.设置字符串的格式 ...
- java 数组批量赋值_JAVA中数组赋值问题
好久没有编程了,今天突然想写点程序,谁知道这个数组的赋值问题给难住了,忘了以前老师说过的,测试程序调用处理类时候,在主程序运行的空间之外又开辟了一块空间,等处理类处理完了后,在返回到主程序的运行空间. ...
- java中给变量赋值_java中变量赋值的理解
1.当赋值的值超出声明变量的范围时候,会报错! byte a =200 //会报错,因超出范围. byte a =(byte)200;//进行一个强制转换,就不会报错,不过会超出范围,超出部分会从头开 ...
- jq js json 转字符串_JS中JSON对象和String之间的互转及处理技巧
json:JavaScript 对象表示法(javascript Object Notation),其实JSON就是一个javaScript的对象(Object)而已. 如有不清楚JSON,可以去w3 ...
最新文章
- Mysql主从同步延迟问题及解决方案
- Codeforces Round #481 (Div. 3)【完结】
- matlab system object,通过 System object 实现模块
- 神奇的x -x,Lowbit函数的实现方式!
- 信息学奥赛一本通C++语言——1039:判断数正负
- 47 MM配置-采购-条件-定价过程-定义方案确认
- 织梦charset.func.php,织梦程序百度php主动推送代码,亲测可用!
- 毕业设计一周一记02
- php合图,php合并图片
- mysql中Group_concat,查找列名,将字符串转换为数字比较大小等杂项记录
- 解决Firefox火狐打不开Axure原型图
- nmn成分是什么,吃nmn对身体有哪些好处,掌握知识点
- CodeForces 85D Sum of Medians Splay | 线段树
- vim autoformat php,vim - 如何在VI中整理HTML文件的缩进?
- Oracle创建同义词
- 华为胡厚崑:不让任何一个人在数字世界中掉队
- Tableau表计算(1):计算类型
- python中true_python中的true是什么
- 斯密特正交化+多项式拟合
- CANape使用记录(一):CANape新建工程及标定观测