博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javaScript中简单数据类型和复杂数据类型赋值拷贝的理解
阅读量:6449 次
发布时间:2019-06-23

本文共 2257 字,大约阅读时间需要 7 分钟。

在js中将一个值a赋值给另一个值b,在什么情况下改变了b的值会影响a的值?在知道哪种类型赋值后改变值会影响原对象的情况下该怎么做才不会影响原对象?就是这里需要讨论的问题。

首先是哪种类型赋值后改变赋值后的值会影响到被赋值的值?

let a = 1;let b = a;b = 2;console.log(a) // 1let obj = {a: 1}let obj2 = obj;obj2.a = 2;console.log(obj) // {a: 2}

从这里我们可以知道:简单数据类型的number赋值后就算改变赋值后的值也不会影响到其本身,但是对象复制后改变了赋值后的值就会影响到其本身。

原理:

javaScript中的数据类型分为两类,简单数据类型和复杂数据类型;

1.简单数据类型:包括数值,字符串、布尔值、null、undefined;
2.复杂数据类型:对象即属性的集合(function、Array、Object);

先了解数据类型在计算机中的存储;

1.简单数据类型:存储的是对象的原始数据;
2.复杂数据类型:对象的原型也是引用类型,对象类型的值单独存放。对象原型的方法和属性放在内存中,通过原型链的方式来指向这个地址;所以对象类型存储的是对象的引用地址;

对象类型在复制的时候,只是将对象的引用复制了,将a对象的引用地址值赋值给了b

所以在b改变对象属性值的时候,a的引用也发生了改变,它们在内存中获取的都是同一个对象;

如果想要复制一个复杂数据类型却不想影响原对象,此时就需要用到深拷贝/浅拷贝。

浅拷贝:

首先由一个数组[1,2,3]或对象{name:'porco', age:1},这样的数组或对象中的值统一不为[数组array]或[对象obj]的只有一层数据结构的简单对象,被称为浅拷贝对象,如果单纯的赋值使用例如let a = [1,2,3],如果改变了a,那么原数组也会相应的被改变,对象也是一样。所以遇到这种情况,想要复制的对象的改变不想影响到原对象,就需要浅拷贝方法:如下

/*** 浅拷贝对象:**/let obj = {a:1,b:2}let obj2 = {};/*方法1*/for(let e in obj) {    obj2[e] = obj[e]}/*方法2*/Object.keys(obj).forEach(e => {    obj2[e] = obj[e]})obj2.a = 0;console.log(obj2) //{a:0, b:2}console.log(obj) //{a:1, b:2}/*这里还可以使用两种es6浅拷贝方式*//*这是直接浅拷贝:*/let obj2 = Object.assign({}, obj);/*以及直接使用拓展运算符拷贝*/let obj2 = {...obj}/*以上四种方式均可作为浅拷贝对象的方式*//***********************************/ /** * 浅拷贝数组: **/let arr = [1,2,3]/*第一种浅拷贝数组方式*/let arr2 = arr.slice(); /*第二种浅拷贝数组方式*/let arr2 = arr.concat();/*第三种浅拷贝数组方式*/let arr2 = [];arr.forEach(e => {    arr2.push(e)})arr2.[0] = 0;console.log(arr2) //[0,2,3]console.log(arr) //[1,2,3]

深拷贝:

当对象中的第一层级有一项是数组或对象,浅拷贝失效,例如:let a = [{a:1}]或let a = {a:{aa:1}},这样,使用上面的方法都会失效。这时必须使用深拷贝
1、最简单的办法

let BBB = JSON.parse(JSON.stringify(AAA))

这种方法简单适用于普通场景,但是也会抛弃对象的constructor,不管之前的构造函数什么样,深拷贝后都会变成object.这种方法能正确处理的对象只有 Number, String, Boolean, Array, 并且能用jso格式直接表示的数据结构。

2、一个递归方法:

function deepClone(obj) {    let objClone = Array.isArray(obj) ? [] : {};    if(obj && typeof obj === "object") {        for(let key in obj) {            if(obj.hasOwnProperty(key)) {                if(obj[key] && typeof obj[key] === "object") {                    objClone[key] = deepClone(obj[key]);                } else {                    objClone[key] = obj[key];                    }             }         }     }    return objClone}

以上就是讨论了哪些值类型赋值不需要使用拷贝,哪些值类型赋值需要浅拷贝,哪些值类型赋值需要深拷贝

转载地址:http://dqlwo.baihongyu.com/

你可能感兴趣的文章
查看linux中的TCP连接数
查看>>
Multipart HTTP Requests
查看>>
Linux常用命令
查看>>
数据库高速缓冲区(database buffer cahce)
查看>>
Shell脚本首枚
查看>>
JDK BitSet实现原理
查看>>
vue + vue-router 懒加载 import / resolve+require
查看>>
EXC_BAD_ACCESS的排查
查看>>
当你忘了虚拟机的密码
查看>>
CentOS6.5下设置静态IP
查看>>
Hbase Replication 介绍
查看>>
Nginx配置服务器静态文件支持跨域访问
查看>>
iOS 获取本地视频的缩略图
查看>>
Ubuntu 安装QQ
查看>>
【Android学习笔记】二、创建项目 安装卸载apk
查看>>
show virtual keyboard
查看>>
【转载】Linux升级安装GCC
查看>>
TCPDUMP命令详解
查看>>
value-ref, key-ref, ref local, ref bean
查看>>
shell if怎么判断参数有值
查看>>