JS中的两种数据类型及实现引用类型的深拷贝的方
一.前言
我们知道,在JS中数据类型按照访问方式和存储方式的不同可分为基本类型和引用类型。
基本类型
基本类型有String、Boolean、Number,Undefined、Null,这些基本类型都是按值传递的,也称为值类型。
引用类型
引用类型有对象、数组、函数,它们都是按引用访问的。
二.存储方式区别
基本类型和引用类型由于两者在内存中存储的方式不同,造成两者访问的方式也不同。其中,基本类型存储在内存的栈中,是按值访问;引用类型存储在内存的堆中,是按引用访问。可如下图所示
当有
var n1 = 10; var n2 = 10; var arr1 = [1,2,3,4] var arr2 = [1,2,3,4]
其在内存中存储方式如图
值类型是在栈中直接保存的变量的实际值,而引用类型在栈中仅仅保存的是变量指向堆中的地址,从上图中可以看出,值类型的变量n1和n2都是10,在栈中却为这两个变量分别开辟了两块空间来存储,而引用类型的变量arr1和arr2也相同,在堆中仅仅开辟了一块内存来存储,而在栈中存储的是这两个变量指向堆中的地址,这两个变量都指向堆中的同一片地址。
三.拷贝区别
正是由于两者在存储方式上的不同,造成了两者在拷贝时的差异。,先看两段代码
var n1 = 10; //将n1拷贝给n2 var n2 = n1; n1 = 12; console.log(n1); console.log(n2);
先定义变量n1=10,然后将n1拷贝给n2,再接着改变n1的值为12,分别打印n1和n2的值,打印结果为
从结果中我们可以看到,n1变为12了,n2不受影响,依旧是10。
再看一段代码
var arr1 = [1,2,3,4] //将arr1拷贝给arr2 var arr2 = arr1; //向arr1中尾部添加一个元素5 arr1.push(5); console.log(arr1); console.log(arr2);
先定义数组arr1,然后将arr1拷贝给arr2,再接着向arr1中尾部追加一个元素,分别打印arr1和arr2的值,打印结果为
从结果中我们可以看到我们先将arr1拷贝给了arr2,当我们改变arr1时,arr2也跟着一起改变了。这印证了前文所说的,arr1和arr2实际上是指向了内存中的同一片地址,当arr1发生变化时,实际上是将指向的这片内存地址中的数据变化了,而arr2也指向的是这片地址,所以arr2也会跟着变化。
上面代码中的arr2=arr1,就是我们俗称的浅拷贝,浅拷贝仅仅拷贝的是变量名,其在内存的存储没有被拷贝,指向的还是同一片内存地址,这就是造成了一个变化一个也跟着变化,这在日常开发中不是我们想要的。
那如何实现真正的拷贝呢?
四.实现深拷贝
真正的拷贝,就是拷贝过后,arr1和arr2指向的不再是同一片内存地址,而是分别指向各自的地址,这样发生变化的时候就不会出现变化,这就是深拷贝。
狼蚁网站SEO优化我们封装一个深拷贝函数,来实现引用类型的深拷贝
//参数p为原对象 //参数c为原对象的类型,若原对象为数组,则传入c为[],若原对象是对象传入c为{},也可不传默认为{} function deepCopy(p,c){ var c = c || {}; for(var i in p){ if(typeof p[i] === "object"){ c[i] = (p[i].constructor === Array)?[]:{}; deepCopy(p[i],c[i]) }else{ c[i] = p[i] } } return c; }
五.测试
//参数p为原对象 //参数c为原对象的类型,若原对象为数组,则传入c为[],若原对象是对象传入c为{},也可不传默认为{} function deepCopy(p,c){ var c = c || {}; for(var i in p){ if(typeof p[i] === "object"){ c[i] = (p[i].constructor === Array)?[]:{}; deepCopy(p[i],c[i]) }else{ c[i] = p[i] } } return c; } //定义数组arr1 var arr1 = [1,2,3,4] //将arr1拷贝给arr2 var arr2 = deepCopy(arr1,[]); //向arr1中尾部添加一个元素5 arr1.push(5); console.log('arr1:',arr1); console.log('arr2:',arr2);
测试结果
结果中可以看到,arr1变化没有引起arr2的变化,实现了真正的拷贝。
以上所述是长沙网络推广给大家介绍的JS中的两种数据类型及实现引用类型的深拷贝的方法,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,长沙网络推广会及时回复大家的!
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程