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的加载方式)
May 20 Javascript
JavaScript的常见兼容问题及相关解决方法(chrome/IE/firefox)
Dec 31 Javascript
Jquery实现textarea根据文本内容自适应高度
Apr 03 Javascript
js+HTML5实现canvas多种颜色渐变效果的方法
Jun 05 Javascript
JS中使用mailto实现将用户在网页中输入的内容传递到本地邮件客户端
Oct 08 Javascript
javaScript生成支持中文带logo的二维码(jquery.qrcode.js)
Jan 03 Javascript
AngularJS的ng-repeat指令与scope继承关系实例详解
Jan 21 Javascript
超全面的vue.js使用总结
Feb 12 Javascript
Bootstrap DateTime Picker日历控件简单应用
Mar 25 Javascript
详解利用Angular实现多团队模块化SPA开发框架
Nov 27 Javascript
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
Sep 12 Javascript
Javascript查看大图功能代码实现
May 07 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 similar text计算两个字符串相似度
2015/11/06 PHP
thinkPHP线上自动加载异常与修复方法实例分析
2016/12/01 PHP
laravel清除视图缓存的代码
2019/10/23 PHP
ext监听事件方法[初级篇]
2008/04/27 Javascript
jquery 模拟类搜索框自动完成搜索提示功能(改进)
2010/05/24 Javascript
关于 文本框默认值 的操作js代码
2012/01/12 Javascript
jQuery实现平滑滚动的标签分栏切换效果
2015/08/28 Javascript
基于JavaScript实现一定时间后去执行一个函数
2015/12/14 Javascript
sso跨域写cookie的一段js脚本(推荐)
2016/05/25 Javascript
JavaScript中removeChild 方法开发示例代码
2016/08/15 Javascript
AngularJS 自定义指令详解及示例代码
2016/08/17 Javascript
Jquery uploadify 多余的Get请求(404错误)的解决方法
2017/01/26 Javascript
JS html时钟制作代码分享
2017/03/03 Javascript
vue.js实现点击后动态添加class及删除同级class的实现代码
2018/04/04 Javascript
判断文字超过2行添加展开按钮,未超过则不显示,溢出部分显示省略号
2019/04/28 Javascript
gulp构建小程序的方法步骤
2019/05/31 Javascript
详解iview的checkbox多选框全选时校验问题
2019/06/10 Javascript
小程序分页实践之编写可复用分页组件
2019/07/18 Javascript
微信JS-SDK实现微信会员卡功能(给用户微信卡包里发送会员卡)
2019/07/25 Javascript
jQuery操作动画完整实例分析
2020/01/10 jQuery
前端vue+elementUI如何实现记住密码功能
2020/09/20 Javascript
js实现简易点击切换显示或隐藏
2020/11/29 Javascript
Python中函数的用法实例教程
2014/09/08 Python
Python实现按中文排序的方法示例
2018/04/25 Python
实践Vim配置python开发环境
2018/07/02 Python
PyTorch 1.0 正式版已经发布了
2018/12/13 Python
对python中list的拷贝与numpy的array的拷贝详解
2019/01/29 Python
keras 多任务多loss实例
2020/06/22 Python
Python Web项目Cherrypy使用方法镜像
2020/11/05 Python
利用css3 translate完美实现表头固定效果
2017/02/28 HTML / CSS
俄罗斯童装网上商店:BebaKids
2020/06/06 全球购物
中学生的1000字检讨书
2014/10/11 职场文书
教师党员群众路线教育实践活动心得体会
2014/11/04 职场文书
浅谈golang package中init方法的多处定义及运行顺序问题
2021/05/06 Golang
Python编程中内置的NotImplemented类型的用法
2022/03/23 Python
Python开发五子棋小游戏
2022/05/02 Python