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 相关文章推荐
jquery 图片 上一张 下一张 链接效果(续篇)
Apr 20 Javascript
jQuery循环滚动展示代码 可应用到文字和图片上
May 11 Javascript
JavaScript动态修改网页元素内容的方法
Mar 21 Javascript
详解JavaScript中常用的函数类型
Nov 18 Javascript
jQuery简单实现input文本框内灰色提示文本效果的方法
Dec 02 Javascript
原生js实现tab选项卡切换
Mar 23 Javascript
jQuery的extend方法【三种】
Dec 14 Javascript
vue组件父子间通信之综合练习(聊天室)
Nov 07 Javascript
使用Vue完成一个简单的todolist的方法
Dec 01 Javascript
微信小程序分享功能之按钮button 边框隐藏和点击隐藏
Jun 14 Javascript
浅谈Fetch 数据交互方式
Dec 20 Javascript
微信小程序实现带参数的分享功能(两种方法)
May 17 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实现分页工具类分享
2014/01/09 PHP
ThinkPHP文件上传实例教程
2014/08/22 PHP
一个高效的JavaScript压缩工具下载集合
2007/03/06 Javascript
javascript 类方法定义还是有点区别
2009/04/15 Javascript
JavaScript 面向对象之命名空间
2010/05/04 Javascript
js对数字的格式化使用说明
2011/01/12 Javascript
jquery图片上下tab切换效果
2011/03/18 Javascript
使用jQuery.fn自定义jQuery翻页插件
2013/01/20 Javascript
js清空form表单中的内容示例
2014/05/20 Javascript
纯javascript移动优先的幻灯片效果
2015/11/02 Javascript
js原型链与继承解析(初体验)
2016/05/09 Javascript
浅谈jquery的map()和each()方法
2016/06/12 Javascript
ES6学习教程之对象的扩展详解
2017/05/02 Javascript
laravel5.4+vue+element简单搭建的示例代码
2017/08/29 Javascript
react的滑动图片验证码组件的示例代码
2019/02/27 Javascript
微信小程序点击图片实现长按预览、保存、识别带参数二维码、转发等功能
2019/07/20 Javascript
使用 webpack 插件自动生成 vue 路由文件的方法
2019/08/20 Javascript
JavaScript Event Loop相关原理解析
2020/06/10 Javascript
vue和H5 draggable实现拖拽并替换效果
2020/07/29 Javascript
python数据结构之二叉树的统计与转换实例
2014/04/29 Python
Python如何实现转换URL详解
2019/07/02 Python
python3中使用__slots__限定实例属性操作分析
2020/02/14 Python
Python decimal模块使用方法详解
2020/06/08 Python
Pycharm中使用git进行合作开发的教程详解
2020/11/17 Python
css3中flex布局宽度不生效的解决
2020/12/09 HTML / CSS
Html5实现文件异步上传功能
2017/05/19 HTML / CSS
Bandier官网:奢侈、时尚前卫的健身服装首选目的地
2020/07/05 全球购物
师范应届生语文教师求职信
2013/10/29 职场文书
浪漫婚礼主持词
2014/03/14 职场文书
委托公证书范本
2014/04/03 职场文书
党员个人剖析材料2014
2014/10/08 职场文书
文明班级申报材料
2014/12/24 职场文书
质量保证书怎么写
2015/02/27 职场文书
关爱留守儿童捐款倡议书
2015/04/27 职场文书
房产证明范本
2015/06/19 职场文书
python 如何执行控制台命令与操作剪切板
2021/05/20 Python