JavaScript中引用vs复制示例详析


Posted in Javascript onDecember 06, 2018

前言

好像一般很少人讲到js中的引用和复制,不过弄清楚这个概念可以帮助理解很多东西

先讲一下很基础的东西,看看js中几种数据类型分别传的什么

引用:对象、数组、函数

复制:数字、布尔

字符串单独说明,因为它的特殊性,无法确定是传递引用还是复制数值(因为字符串的值是没法改变的,所以纠结这个问题也是没意义的)但是用于比较的时候显然是属于传值比较

下面来一起看看详细的介绍吧

首先我们看下面这个例子:

let age = 18;
let age2 = age;
console.log(age, age2);

我们会得到以下的值:

18 18

这个相信大家都能很好理解。

那么如果我们改变 age 的值呢?输出会有什么变化?

age = 20;
console.log(age, age2);

我们会得到:

20 18

看到这里大家就奇怪了,上面的结果都很正常啊。

但在 JavaScript 中是有例外的,对于普通数据类型如 integer,string,boolean 可以通过 = 来复制这个变量,但对于 array 和 object 数据类型,= 只能起到引用的效果。

大家可以看下面这个例子:

let arr = ['wes', 'bob', 'faker'];
let arr2 = arr;
console.log(arr2, arr);
arr[2] = 'dean';
console.log(arr2, arr);

得到的结果是:

["wes", "bob", "faker"] ["wes", "bob", "faker"]
["wes", "bob", "dean"] ["wes", "bob", "dean"]

我们会发现随着 arr 的改变,arr2 也会跟着改变。

说明 arr2 并没有复制 arr 的值,只是引用了它,它们都指向同一个内存中的值。

object 也是一样的:

let obj = {
 age: 19,
 name: 'like',
 last: 'jam'
};
let obj2 = obj;
console.log(obj, obj2);
obj.age = 50;
console.log(obj, obj2);

得到的结果是:

{age: 19, name: "like", last: "jam"} {age: 19, name: "like", last: "jam"}
{age: 50, name: "like", last: "jam"} {age: 50, name: "like", last: "jam"}

那么如何复制 array 和 object 呢?

复制 array 的方法:

方法1:

let arr2 = [].concat(arr);

方法2:

let arr2 = arr.slice();

方法3:

let arr2 = Array.from(arr);

方法4:

let arr2 = [...arr];

一般我们比较常用的是方法3和方法4,方法1和方法2比较取巧,但都是可以达到复制 array 的目的的。

ps: [...arr] 是 ES6 中的方法。

复制 object 的方法:

方法1:

let obj2 = Object.assign({}, obj);

方法2:

let obj2 = {...obj};

方法1和方法2都有个缺点,它们只会复制对象的第一层。

看下面这个例子:

let obj = {
 number: 12,
 name: {
  first: 'bob',
  last: 'evil'
 }
};
let obj2 = Object.assign({}, obj);
obj.number = 50;
console.log(obj, obj2);

我们会得到下面的结果:

obj = {
    number: 50,
    name: {
        first: 'bob',
        last: 'evil'
    }
}

obj2 = {
    number: 12,
    name: {
        first: 'bob',
        last: 'evil'
    }
}

但如果我们改变第二层的值:

obj.name.first = 'sam';
console.log(obj, obj2);

obj = {
    number: 50,
    name: {
        first: 'sam',
        last: 'evil'
    }
}

obj2 = {
    number: 12,
    name: {
        first: 'sam',
        last: 'evil'
    }
}

我们发现对象第二层依旧是引用的,并没有实现复制。

那么怎么复制一个完整的 object 呢?

最简单的方法就是使用第三方函数库 lodash ,它提供了 clone 和 deepclone 完全可以满足日常的需求。

object 的复制因为要考虑到很多因素,我会另开一篇,专门整理。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Jquery下:nth-child(an+b)的使用注意
May 28 Javascript
JavaScript包装对象使用介绍
Aug 29 Javascript
jquery增加时编辑jqGrid(实例代码)
Nov 08 Javascript
node.js WEB开发中图片验证码的实现方法
Jun 03 Javascript
jquery实现在页面加载的时自动为日期插件添加当前日期
Aug 20 Javascript
JQuery拖动表头边框线调整表格列宽效果代码
Sep 10 Javascript
js仿iphone秒表功能 计算平均数
Jan 11 Javascript
@ResponseBody 和 @RequestBody 注解的区别
Mar 08 Javascript
Vue组件通信之Bus的具体使用
Dec 28 Javascript
微信小程序实现城市列表选择
Jun 05 Javascript
JavaScript写个贪吃蛇小游戏(超详细)
Mar 17 Javascript
js实现飞机大战游戏
Aug 26 Javascript
使用jQuery动态设置单选框的选中效果
Dec 06 #jQuery
express+vue+mongodb+session 实现注册登录功能
Dec 06 #Javascript
如何使用puppet替换文件中的string
Dec 06 #Javascript
详解vantUI框架在vue项目中的应用踩坑
Dec 06 #Javascript
基于element-ui组件手动实现单选和上传功能
Dec 06 #Javascript
JavaScript 中 JSON.parse 函数 和 JSON.stringify 函数
Dec 05 #Javascript
在Vant的基础上实现添加表单验证框架的方法示例
Dec 05 #Javascript
You might like
用PHP书写安全的脚本代码
2012/02/05 PHP
php 深入理解strtotime函数的使用详解
2013/05/23 PHP
基于PHP实现商品成交时发送短信功能
2016/05/11 PHP
php显示页码分页类的封装
2017/06/08 PHP
php实现的统计字数函数定义与使用示例
2017/07/26 PHP
jquery ready()的几种实现方法小结
2010/06/18 Javascript
40个有创意的jQuery图片、内容滑动及弹出插件收藏集之一
2011/12/31 Javascript
jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate)
2014/05/22 Javascript
js触发select onchange事件的小技巧
2014/08/05 Javascript
实现无刷新联动例子汇总
2015/05/20 Javascript
JS+CSS实现带有碰撞缓冲效果的竖向导航条代码
2015/09/15 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
2016/05/17 Javascript
ECMAScript6 新特性范例大全
2017/03/24 Javascript
JavaScript用二分法查找数据的实例代码
2017/06/17 Javascript
移动端网页开发调试神器Eruda的介绍与使用技巧
2017/10/30 Javascript
详解Node 定时器
2018/02/26 Javascript
vue项目中添加单元测试的方法
2018/07/21 Javascript
微信小程序页面间传值与页面取值操作实例分析
2019/04/30 Javascript
Vue中跨域及打包部署到nginx跨域设置方法
2019/08/26 Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
2020/03/23 Javascript
TensorFlow 模型载入方法汇总(小结)
2018/06/19 Python
Python中如何导入类示例详解
2019/04/17 Python
使用Python实现跳一跳自动跳跃功能
2019/07/10 Python
python多环境切换及pyenv使用过程详解
2019/09/27 Python
TensorFlow:将ckpt文件固化成pb文件教程
2020/02/11 Python
pandas的resample重采样的使用
2020/04/24 Python
Python环境配置实现pip加速过程解析
2020/11/27 Python
Canvas 文字碰撞检测并抽稀的方法
2019/05/27 HTML / CSS
罗德与泰勒百货官网:Lord & Taylor
2016/08/12 全球购物
李维斯法国官网:Levi’s法国
2019/07/13 全球购物
意大利在线药房:Saninforma
2021/02/11 全球购物
大学本科毕业生的自我鉴定
2013/11/26 职场文书
酒店前厅员工辞职信
2014/01/08 职场文书
文明风采获奖感言
2014/02/18 职场文书
导师推荐信范文
2014/05/09 职场文书
oracle通过存储过程上传list保存功能
2021/05/12 Oracle