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 相关文章推荐
JavaScript 全面解析各种浏览器网页中的JS 执行顺序
Feb 17 Javascript
js加强的经典分页实例
Mar 15 Javascript
JavaScript实现多维数组的方法
Nov 20 Javascript
js对象转json数组的简单实现案例
Feb 28 Javascript
js操作输入框提示信息且响应鼠标事件
Mar 25 Javascript
再探JavaScript作用域
Sep 24 Javascript
Javascript原型链和原型的一个误区
Oct 22 Javascript
解析浏览器端的AJAX缓存机制
Jun 21 Javascript
JavaScript中的splice方法用法详解
Jul 20 Javascript
Popup弹出框添加数据实现方法
Oct 27 Javascript
Vue axios设置访问基础路径方法
Sep 19 Javascript
关于vue3默认把所有onSomething当作v-on事件绑定的思考
May 15 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 adodb连接带密码access数据库实例,测试成功
2008/05/14 PHP
PHP 配置文件中open_basedir选项作用
2009/07/19 PHP
ThinkPHP CURD方法之limit方法详解
2014/06/18 PHP
深入解析PHP中foreach语句控制数组循环的用法
2015/11/30 PHP
bindParam和bindValue的区别以及在Yii2中的使用详解
2018/03/12 PHP
告诉大家什么是JSON
2008/06/10 Javascript
input 高级限制级用法
2009/03/26 Javascript
ASP小贴士/ASP Tips javascript tips可以当桌面
2009/12/10 Javascript
juqery 学习之五 文档处理 包裹、替换、删除、复制
2011/02/11 Javascript
Javascript 中的 call 和 apply使用介绍
2012/02/22 Javascript
Js nodeType 属性全面解析
2013/11/14 Javascript
js 概率计算(简单版)
2017/09/12 Javascript
js实现图片区域可点击大小随意改变(适用移动端)代码实例
2019/09/11 Javascript
react使用CSS实现react动画功能示例
2020/05/18 Javascript
webpack安装配置与常见使用过程详解(结合vue)
2020/06/01 Javascript
Vue页面手动刷新,实现导航栏激活项还原到初始状态
2020/08/06 Javascript
解决vue页面刷新,数据丢失的问题
2020/11/24 Vue.js
超详细小程序定位地图模块全系列开发教学
2020/11/24 Javascript
详解微信小程序(Taro)手动埋点和自动埋点的实现
2021/03/02 Javascript
python生成器的使用方法
2013/11/21 Python
Python利用splinter实现浏览器自动化操作方法
2018/05/11 Python
Python二叉树的遍历操作示例【前序遍历,中序遍历,后序遍历,层序遍历】
2018/12/24 Python
使用python telnetlib批量备份交换机配置的方法
2019/07/25 Python
如何解决django-celery启动后迅速关闭
2019/10/16 Python
浅谈Python的方法解析顺序(MRO)
2020/03/05 Python
python:解析requests返回的response(json格式)说明
2020/04/30 Python
python字典key不能是可以是啥类型
2020/08/04 Python
艺术专业大学生自我评价
2013/09/22 职场文书
大学生军训感想
2014/02/16 职场文书
水污染治理工程专业自荐信
2014/06/21 职场文书
邮政竞聘演讲稿
2014/09/03 职场文书
劳模先进事迹材料
2014/12/24 职场文书
幼儿园推普周活动总结
2015/05/07 职场文书
python爬虫之爬取笔趣阁小说
2021/04/22 Python
PHP遍历数组的6种方式总结
2021/11/17 PHP
python opencv将多个图放在一个窗口的实例详解
2022/02/28 Python