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 存在陷阱 删除某一区域所有节点
May 10 Javascript
js通过googleAIP翻译PHP系统的语言配置的实现代码
Oct 17 Javascript
Javascript模块化编程(三)require.js的用法及功能介绍
Jan 17 Javascript
jQuery(js)获取文字宽度(显示长度)示例代码
Dec 31 Javascript
获取select的value、text值的简单示例(jquery与javascript)
Dec 07 Javascript
JSON与js对象序列化实例详解
Mar 16 Javascript
node.js 用socket实现聊天的示例代码
Oct 17 Javascript
Vue-cli中为单独页面设置背景色的实现方法
Feb 11 Javascript
Vue实现动态创建和删除数据的方法
Mar 17 Javascript
快速解决angularJS中用post方法时后台拿不到值的问题
Aug 14 Javascript
VUE.CLI4.0配置多页面入口的实现
Nov 25 Javascript
angular8和ngrx8结合使用的步骤介绍
Dec 01 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
在windows iis5下安装php4.0+mysql之我见
2006/10/09 PHP
PHP中register_globals参数为OFF和ON的区别(register_globals 使用详解)
2012/02/05 PHP
深入分析php中接口与抽象类的区别
2013/06/08 PHP
Yii中使用PHPExcel导出Excel的方法
2014/12/26 PHP
详解PHP5.6.30与Apache2.4.x配置
2017/06/02 PHP
php实现数组中出现次数超过一半的数字的统计方法
2018/10/14 PHP
巧用replace将文字表情替换为图片
2014/04/17 Javascript
jQuery支持动态参数将函数绑定到事件上的方法
2015/03/17 Javascript
使用Javascript写的2048小游戏
2015/11/25 Javascript
JS锚点的设置与使用方法
2016/09/05 Javascript
整理一下常见的IE错误
2016/11/18 Javascript
浅谈js函数的多种定义方法与区别
2016/11/29 Javascript
jQuery在header中设置请求信息的方法
2017/03/06 Javascript
NodeJS 实现手机短信验证模块阿里大于功能
2017/06/19 NodeJs
Angular X中使用ngrx的方法详解(附源码)
2017/07/10 Javascript
Vue服务器渲染Nuxt学习笔记
2018/01/31 Javascript
Koa2 之文件上传下载的示例代码
2018/03/29 Javascript
Vue.js 中的 v-show 指令及用法详解
2018/11/19 Javascript
详解微信小程序-获取用户session_key,openid,unionid - 后端为nodejs
2019/04/29 NodeJs
JS立即执行的匿名函数用法分析
2019/11/04 Javascript
[17:13]DOTA2 HEROS教学视频教你分分钟做大人-斯拉克
2014/06/13 DOTA
[01:33]真香警告!DOTA2勇士令状不朽珍藏Ⅱ饰品欣赏
2018/06/26 DOTA
Python查找相似单词的方法
2015/03/05 Python
python实现12306抢票及自动邮件发送提醒付款功能
2018/03/08 Python
将python运行结果保存至本地文件中的示例讲解
2019/07/11 Python
Python绘图实现显示中文
2019/12/04 Python
Python + opencv对拍照得到的图片进行背景去除的实现方法
2020/11/18 Python
使用CSS3来代替JS实现交互
2017/08/10 HTML / CSS
MIS软件工程师的面试题
2016/04/22 面试题
DTD的含义以及作用
2014/01/26 面试题
资产评估专业大学生求职信
2013/09/29 职场文书
语文教学随笔感言
2014/02/18 职场文书
企业精神口号
2014/06/11 职场文书
生活小常识广播稿
2015/08/19 职场文书
SQL实现LeetCode(175.联合两表)
2021/08/04 MySQL
python 判断字符串当中是否包含字符(str.contain)
2022/06/01 Python