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是否可实现多线程  深入理解JavaScript定时机制
Dec 22 Javascript
JS保存、读取、换行、转Json报错处理方法
Jun 14 Javascript
jQuery中delegate与on的用法与区别示例介绍
Dec 20 Javascript
javascript中数组的定义及使用实例
Jan 21 Javascript
Vue.js组件tree实现省市多级联动
Dec 02 Javascript
DOM 事件的深入浅出(一)
Dec 05 Javascript
JavaScript实现倒计时跳转页面功能【实用】
Dec 13 Javascript
微信小程序城市定位的实现实例(获取当前所在国家城市信息)
May 17 Javascript
View.post() 不靠谱的地方你知道多少
Aug 29 Javascript
jQuery结合jQuery.cookie.js插件实现换肤功能示例
Oct 14 jQuery
基于Nuxt.js项目的服务端性能优化与错误检测(容错处理)
Oct 23 Javascript
jQuery编写QQ简易聊天框
Aug 27 jQuery
使用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数组函数序列之end() - 移动数组内部指针到最后一个元素,并返回该元素的值
2011/10/31 PHP
PHP下的Oracle客户端扩展(OCI8)安装教程
2014/09/10 PHP
详解WordPress中提醒安装插件以及隐藏插件的功能实现
2015/12/25 PHP
PHP实现将MySQL重复ID二维数组重组为三维数组的方法
2016/08/01 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
ToolTips JQEURY插件之简洁小提示框效果
2011/11/19 Javascript
js查找某元素中的所有图片地址的方法
2014/01/16 Javascript
使用jQuery获取data-的自定义属性
2015/11/10 Javascript
解决jQuery上传插件Uploadify出现Http Error 302错误的方法
2015/12/18 Javascript
JavaScript实现Java中Map容器的方法
2016/10/09 Javascript
微信小程序 获取相册照片实例详解
2016/11/16 Javascript
利用forever和pm2部署node.js项目过程
2017/05/10 Javascript
使用vue如何构建一个自动建站项目
2018/02/05 Javascript
原生JS实现的简单轮播图功能【适合新手】
2018/08/17 Javascript
Vue中div contenteditable 的光标定位方法
2018/08/25 Javascript
关于ckeditor在bootstrap中modal中弹框无法输入的解决方法
2019/09/11 Javascript
vue实现路由不变的情况下,刷新页面操作示例
2020/02/02 Javascript
利用Vue的v-for和v-bind实现列表颜色切换
2020/07/17 Javascript
Android应用开发中Action bar编写的入门教程
2016/02/26 Python
python 全文检索引擎详解
2017/04/25 Python
python获取当前目录路径和上级路径的实例
2018/04/26 Python
Python3.7实现中控考勤机自动连接
2018/08/28 Python
Python 从相对路径下import的方法
2018/12/04 Python
对python当中不在本路径的py文件的引用详解
2018/12/15 Python
Django项目主urls导入应用中views的红线问题解决
2019/08/10 Python
Django3中的自定义用户模型实例详解
2020/08/23 Python
Pytest单元测试框架如何实现参数化
2020/09/05 Python
详解基于Scrapy的IP代理池搭建
2020/09/29 Python
加拿大在线隐形眼镜专家:PerfectLens.ca
2016/11/19 全球购物
Tod’s英国官方网站:意大利奢华手工制作手袋和鞋履
2019/03/15 全球购物
国家励志奖学金获奖感言
2014/01/09 职场文书
2014年销售工作总结与计划
2014/12/01 职场文书
考试作弊检讨书怎么写?
2014/12/21 职场文书
工厂仓管员岗位职责
2015/04/01 职场文书
原告代理词范文
2015/05/25 职场文书
Java tomcat手动配置servlet详解
2021/11/27 Java/Android