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 相关文章推荐
动态添加js事件实现代码
Mar 12 Javascript
jquery原创弹出层折叠效果点击折叠弹出一个层
Mar 12 Javascript
JavaScript判断IE版本型号
Jul 27 Javascript
jQuery实现简易的天天爱消除小游戏
Oct 16 Javascript
Bootstrap选项卡与Masonry插件的完美结合
Jul 06 Javascript
PhotoSwipe异步动态加载图片方法
Aug 25 Javascript
原生JS实现圆环拖拽效果
Apr 07 Javascript
webpack之devtool详解
Feb 10 Javascript
JS中call和apply函数用法实例分析
Jun 20 Javascript
js中的数组对象排序分析
Dec 11 Javascript
JS removeAttribute()方法实现删除元素的某个属性
Jan 11 Javascript
vue+flask实现视频合成功能(拖拽上传)
Mar 04 Vue.js
使用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使用PDO方法详解
2014/12/27 PHP
php找出指定范围内回文数且平方根也是回文数的方法
2015/03/23 PHP
php实现有序数组打印或排序的方法【附Python、C及Go语言实现代码】
2016/11/10 PHP
PHP 模拟登陆功能实例详解
2019/09/10 PHP
用Laravel轻松处理千万级数据的方法实现
2020/12/25 PHP
js location.replace与location.reload的区别
2010/09/08 Javascript
JavaScript中的包装对象介绍
2015/01/27 Javascript
jQuery Mobile弹出窗、弹出层知识汇总
2016/01/05 Javascript
利用js获取下拉框中所选的值
2016/12/01 Javascript
Bootstrap php制作动态分页标签
2016/12/23 Javascript
jquery代码规范让代码越来越好看
2017/02/03 Javascript
Vue项目中引入外部文件的方法(css、js、less)
2017/07/24 Javascript
Angular2监听页面大小变化的解决方法
2017/10/09 Javascript
JS简单添加元素新节点的方法示例
2018/02/10 Javascript
vue中上传视频或图片或图片和文字一起到后端的解决方法
2019/12/01 Javascript
[55:32]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第二场
2018/04/05 DOTA
python实现通过pil模块对图片格式进行转换的方法
2015/03/24 Python
python编写Logistic逻辑回归
2020/12/30 Python
Python数据分析库pandas基本操作方法
2018/04/08 Python
判断python字典中key是否存在的两种方法
2018/08/10 Python
朴素贝叶斯Python实例及解析
2018/11/19 Python
python实现整数的二进制循环移位
2019/03/08 Python
Python Django 添加首页尾页上一页下一页代码实例
2019/08/21 Python
python datetime时间格式的相互转换问题
2020/06/11 Python
python Socket网络编程实现C/S模式和P2P
2020/06/22 Python
python 装饰器的实际作用有哪些
2020/09/07 Python
结合 CSS3 transition transform 实现简单的跑马灯效果的示例
2018/02/07 HTML / CSS
前端H5 Video常见使用场景简介
2020/08/21 HTML / CSS
节省高达65%的城市景点费用:Go City
2019/07/06 全球购物
优秀的个人求职信范文
2014/05/09 职场文书
乡镇爱国卫生月活动总结
2014/06/25 职场文书
2015年个人审计工作总结
2015/04/07 职场文书
《童年的发现》教学反思
2016/02/18 职场文书
基于Redis实现分布式锁的方法(lua脚本版)
2021/05/12 Redis
关于springboot 配置date字段返回时间戳的问题
2021/07/25 Java/Android
如何利用golang运用mysql数据库
2022/03/13 Golang