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 相关文章推荐
use jscript List Installed Software
Jun 11 Javascript
Javascript 篱式条件判断
Aug 22 Javascript
Javascript和Ajax中文乱码吐血版解决方案
Dec 21 Javascript
ASP.NET中基于JQUERY的高性能的TreeView补充
Feb 23 Javascript
jQuery判断密码强度实现思路及代码
Apr 24 Javascript
js怎么判断flash swf文件是否加载完毕
Aug 14 Javascript
C++中的string类的用法小结
Aug 07 Javascript
javascript流程控制语句集合
Sep 18 Javascript
Mint UI 基于 Vue.js 移动端组件库
Nov 07 Javascript
JS获取子节点、父节点和兄弟节点的方法实例总结
Jul 06 Javascript
Bootstrap Table实现定时刷新数据的方法
Aug 13 Javascript
Vue基本指令实例图文讲解
Feb 25 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
网络资源
2006/10/09 PHP
php实现扫描二维码根据浏览器类型访问不同下载地址
2014/10/15 PHP
PHP实现搜索相似图片
2015/09/22 PHP
教大家制作简单的php日历
2015/11/17 PHP
谈谈 PHP7新增功能
2015/12/16 PHP
php metaphone()函数的定义和用法
2016/05/15 PHP
php进行ip地址掩码运算处理的方法
2016/07/11 PHP
PHP中FTP相关函数小结
2016/07/15 PHP
PHP 5.6.11 访问SQL Server2008R2的几种情况详解
2016/08/08 PHP
几个javascript操作word的参考代码
2009/10/26 Javascript
jquery 学习之一 对象访问
2010/11/23 Javascript
jQuery的slideToggle方法实例
2013/05/07 Javascript
js+CSS实现弹出居中背景半透明div层的方法
2015/02/26 Javascript
js完美实现@提到好友特效(兼容各大浏览器)
2015/03/16 Javascript
jQuery插件EnPlaceholder实现输入框提示文字
2015/06/05 Javascript
javascript基础知识分享之类与函数化
2016/02/13 Javascript
jQuery列表检索功能实现代码
2017/07/17 jQuery
基于jQuery实现的单行公告活动轮播效果
2017/08/23 jQuery
在 vue-cli v3.0 中使用 SCSS/SASS的方法
2018/06/14 Javascript
JavaScript函数、闭包、原型、面向对象学习笔记
2018/09/06 Javascript
[49:08]Secret vs VP 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Django model反向关联名称的方法
2018/12/15 Python
numpy基础教程之np.linalg
2019/02/12 Python
Python pip替换为阿里源的方法步骤
2019/07/02 Python
Python+Django+MySQL实现基于Web版的增删改查的示例代码
2020/05/13 Python
解决django migrate报错ORA-02000: missing ALWAYS keyword
2020/07/02 Python
python 实现IP子网计算
2021/02/18 Python
20佳惊艳的HTML5应用程序示例分享
2011/05/03 HTML / CSS
澳大利亚第一的设计师礼服租赁网站:GlamCorner
2017/08/13 全球购物
新学期决心书
2014/03/11 职场文书
C++程序员求职信范文
2014/04/14 职场文书
校园安全广播稿范文
2014/09/25 职场文书
幼儿园教师暑期培训心得体会
2016/01/09 职场文书
关于保护环境的建议书
2019/06/24 职场文书
Python编写可视化界面的全过程(Python+PyCharm+PyQt)
2021/05/17 Python
Python下opencv使用hough变换检测直线与圆
2021/06/18 Python