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的获取标签名的代码
Jul 16 Javascript
jquery 插件实现瀑布流图片展示实例
Apr 03 Javascript
javascript动态获取登录时间和在线时长
Feb 25 Javascript
微信+angularJS的SPA应用中用router进行页面跳转,jssdk校验失败问题解决
Sep 09 Javascript
微信小程序-详解数据缓存
Nov 24 Javascript
jQuery学习笔记之入门
Dec 14 Javascript
原生js封装自定义滚动条
Mar 24 Javascript
微信小程序-滚动消息通知的实例代码
Aug 03 Javascript
详解如何使用 vue-cli 开发多页应用
Dec 16 Javascript
vue element-ui table表格滚动加载方法
Mar 02 Javascript
Ant design vue中的联动选择取消操作
Oct 31 Javascript
原生JavaScript实现购物车
Jan 10 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
Adodb的十个实例(清晰版)
2006/12/31 PHP
静态图片的十一种滤镜效果--不支持Ie7及非IE浏览器。
2007/03/06 Javascript
分享XmlHttpRequest调用Webservice的一点心得
2012/07/20 Javascript
js控制表单操作的常用代码小结
2013/08/15 Javascript
js验证整数加保留小数点的简单实例
2013/12/02 Javascript
jQuery模拟点击A标记示例参考
2014/04/17 Javascript
jquery仿搜索自动联想功能代码
2014/05/23 Javascript
jquery+php实现搜索框自动提示
2014/11/28 Javascript
JavaScript中setFullYear()方法的使用详解
2015/06/11 Javascript
一种新的javascript对象创建方式Object.create()
2015/12/28 Javascript
判断是否存在子节点的实现代码
2016/05/18 Javascript
JavaScript实现Fly Bird小游戏
2016/12/15 Javascript
详解开源的JavaScript插件化框架MinimaJS
2017/10/26 Javascript
利用jQuery+localStorage实现一个简易的计时器示例代码
2017/12/25 jQuery
vuex进阶知识点巩固
2018/05/20 Javascript
ES6 fetch函数与后台交互实现
2018/11/14 Javascript
vue实现一个矩形标记区域(rectangle marker)的方法
2020/10/28 Javascript
Python编程实现生成特定范围内不重复多个随机数的2种方法
2017/04/14 Python
Python语言实现百度语音识别API的使用实例
2017/12/13 Python
pyqt5中QThread在使用时出现重复emit的实例
2019/06/21 Python
Pycharm和Idea支持的vim插件的方法
2020/02/21 Python
python else语句在循环中的运用详解
2020/07/06 Python
Django ModelForm组件原理及用法详解
2020/10/12 Python
python 通过exifread读取照片信息
2020/12/24 Python
python 使用xlsxwriter循环向excel中插入数据和图片的操作
2021/01/01 Python
美国户外生活方式品牌:Eddie Bauer
2016/12/28 全球购物
教育技术职业规划范文
2014/03/04 职场文书
不拖欠农民工工资承诺书
2014/03/31 职场文书
新闻人物通讯稿
2014/10/09 职场文书
困难补助申请报告
2015/05/19 职场文书
网吧温馨提示
2015/07/17 职场文书
2016春季校长开学典礼致辞
2015/11/26 职场文书
Python+uiautomator2实现自动刷抖音视频功能
2021/04/29 Python
MySQL中使用or、in与union all在查询命令下的效率对比
2021/05/26 MySQL
使用Vue3+Vant组件实现App搜索历史记录功能(示例代码)
2021/06/09 Vue.js
sql注入教程之类型以及提交注入
2021/08/02 MySQL