如何理解JavaScript中给变量赋值,是引用还是复制

一、JavaScript中值的类型

JavaScript中的值分为2大类:基本类型和引用类型。每种类型下面又分为5种类型。

基本类型:

     数字类型:Number;字符串类型:String;布尔类型:Boolean(true和false);Undefined;Null。

引用类型:

     函数、数组、日期、正则、错误。

注意:所有的引用类型都是对象,也就是Object对象下的一个类。

二、值和引用

    在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型值。

    对基本类型,是按值访问的,即通过值复制的方式来赋值和传递。

    对引用类型,是按引用访问的,即通过引用复制的方式赋值和传递。在操作对象时,实际上是在操作对象的引用,而不是实际的对象。

下面通过示例来理解两者的区别。

例1:

    以数字基本类型值为例,将数字赋给变量a,此时a持有的是该值的一个复制本。再将a赋给变量b,此时b持有的是该值得另一个复制本,不论b怎么变化,都不会影响a的值。

    注意:所有的基本类型值都是不会变的。比如一个字符串"abcd",它的值永远是"abcd",不可能发生改变。如果把它赋给一个变量,var x="abcd",然后给x赋其他的值,那么x的值可以改变,但是abcd"这个字符串本身的值没有发生任何变化。包括使用某些自带的函数,比如x.toUpperCase();这个函数返回的是x字符串的大写形式"ABCD"。注意,是“返回”一个值,而不是改变原有的值。此时,变量x的值仍然是"adcd",除非你使用了x=x.toUpperCase()。(即重新对变量赋值了)

    对于基本类型,将其值赋给一个变量时,就是将这个值赋值给了变量,值本身不会发生任何变化。在给变量重新赋值后,变量的值就变化了。变量之间是可以比较的,比较的就是他们本身的值。

例2:

    以数组引用类型为例。JavaScript支持在定义变量的时候同时给它赋值,即var a=[1,2,3]同时定义一个对象并将其赋值给变量。

    定义一个对象(数组[1,2,3]),此时这个对象在内存中建立。当给把这个对象赋值给一个变量时,变量a仅仅是对这个对象的引用,而不是将该对象复制到了该变量中。即变量a中存储的是指向对象的地址。将a的值赋给b,也即将a中的地址赋给了变量b。这是变量a和b都指向同一个对象。所以b值得改变就会直接引起对象本身的改变,因为变量a也指向这个数组,所以a的值肯定也会发生变化。

    注意:对象的比较与基本类型值不同。即使两个对象完全相同,比如两个完全相同的数组,它们也是不相等的。只有两个变量指向同一个对象时,它们才是相等的。如:

var a = [1,2,3],b = [1,2,3];
console.log(a===b);//false
var c=a;
console.log(c===a);//ture

 

例3:

    例3与例2的区别在于,对b进行了重新赋值操作,b就不再是引用a的指向,并与a的指向没有任何关系,而是指向了一个新的数组[1,2,3,4],所以b的操作也不再影响到a指向的值。

例4:函数-无重新赋值

    将数组赋值给变量a后,a指向数组[1,2,3]。调用函数foo(a)之后,向数组中插入数字4,原数组发生变化,所以a也跟着变成[1,2,3,4]。

例5:函数-有重新赋值

  • 定义数组[1,2,3]并赋值给变量a,a指向该数组。
  • 调用函数foo(a),执行的操作是:

        1、向原数组中插入数字4,原数组变成[1,2,3,4];

        2、定义新数组[4,5,6],并重新赋值给a。此时变量指向了新数组,原数组保持[1,2,3,4]不变;

        3、向变量中插入数字7,由于此时变量指向了新数组,所以此步操作改变了新数组[4,5,6],新数组又变成另一个新数组[4,5,6,7];

        4、执行console.log操作,显示的是这个最新的数组,即[4,5,6,7]。

  • 函数外执行console.log操作。由于函数中,只有第一步操作改变了原数组,后续操作改变的是新赋值的数组[4,5,6](新赋值之后,变量a指向了该新数组,所有后续操作,都是针对的新数组),所有该步操作的结果显示的是[1,2,3,4]。

例6:函数-清空当前引用的数组

  • 定义数组[1,2,3]并赋值给变量a,a指向该数组。
  • 调用函数foo(a),执行的操作是:

        1、向原数组中插入数字4,原数组变成[1,2,3,4];

        2、清空数组。由于此时变量仍然指向原数组,所以此处操作针对的是原数组,即清空原数组;

        3、向数组中插入数字4,5,6,7。由于没有重新赋值操作,变量仍然指向原数组,所以原数组变为新数组[4,5,6,7];

        4、执行console.log操作,显示的是这个最新的数组,即[4,5,6,7]。

  • 函数外执行console.log操作,由于函数中变量都没有重新赋值,所以每一步操作针对的都是原数组,最终原数组变成了这个最新的数组,即[4,5,6,7]。

三、更多例子

例1:

    当多个变量持有同一对象的引用时,通过其中的任何一个,都可以改变对象。

例2:

     对比代码可知,test1和test2的区别在于,变量a在test1中不断地赋值新的引用,导致a与b持有的引用不同,后面向a添加的属性,b都无法访问到。

转载于:https://www.cnblogs.com/haidaojiege/p/6694271.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401184.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CommonCollection1反序列化链学习

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 CommonsCollection1 1、前置知识 1.1、反射基础知识 1.1.1、 对象与类的基础知识 类(class)&am…

【英语天天读】第一场雪

作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ --Henry Wadsworth Longfellow The first snow came. How beautiful it was, falling so silently, all day long, all night long, on the mountains, on the meadows, on the roofs of the living, o…

性能测试的目的与类型

1.性能测试的目的 (1)评估系统的能力:测试中得到的负荷和响应时间数据可以被用于验证所计划的模型的能力,并帮助作出决策;(2)寻找系统瓶颈,进行系统调优;(4)检测软件中的问题;(5)验证稳定性、可靠性&#x…

求三位数的质数

没做出来啊&#xff0c;原来有这么多方法啊。首先&#xff0c;我连质数是什么都不知道&#xff01;质数&#xff1a;只能被本身和1整除的数帖子里回复了不少方法&#xff1a;class Zhishu {public static void main(String[] args) {int count0;for(int i1;i<100;i){count0…

[转]VS2010+MFC解析Excel文件中数据

本文转自&#xff1a;http://www.vcfans.com/2010/08/vs2010-mfc-excel-file-in-the-data-analysis.html 前两天折腾一个小功能&#xff0c;需求是解析Excel中的数据出来。网上一般使用的方案&#xff1a;1. ODBC当数据库来操作。2. 使用第三方的类库3. 使用COM调用Excel.exe中…

MySQL索引机制(详细+原理+解析)

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 MySQL索引机制 永远年轻&#xff0c;永远热泪盈眶 一.索引的类型与常见的操作 前缀索引 MySQL 前缀索引能有效减小索引文…

War-Driving(战争驾驶***)

War-Driving总结性的文章 以后应该不会在到这方面过多的下功夫了。点我下载转载于:https://blog.51cto.com/0x007/1586376

array sort - 4 : merge sort

NULL转载于:https://www.cnblogs.com/roadmap99/p/6698809.html

带研发团队后的日常思考1 初级管理者的困惑

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 带研发团队后的日常思考1 初级管理者的困惑 前言&#xff1a; 本人于2020年4月开始接触管理工作到现在有2年的时间&#…

短连接生成器——让你的url地址长度变短

http://www.henshiyong.com/tools/sina-shorten-url.php 转载于:https://www.cnblogs.com/mangu-uu/archive/2012/10/15/2724290.html

JS函数调用的四种方法

js的函数调用会免费奉送两个而外的参数就是 this 和 arguments 。arguments是参数组&#xff0c;他并不是一个真实的数组&#xff0c;但是可以使用.length方法获得长度。 书上有说4中调用方式&#xff1a; 方法调用模式函数调用模式构造器调用模式apply调用模式下面我们来看看一…

Django项目引入NPM和gulp管理前端资源

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 前言 之前写了一篇《Asp-Net-Core开发笔记&#xff1a;使用NPM和gulp管理前端静态文件》&#xff0c;现在又来用Django开发…

有声听书

各位领导/投资人/用户/合作伙伴&#xff1a; 我们的产品《有声听书》是为了解决中年人&#xff0c;中老年人的痛苦。他们需要丰富生活&#xff0c;但是现有的方案并没有很好地解决这些需求&#xff0c;我们有独特的办法&#xff0c;有戏剧&#xff0c;书的音频能给用户带来好处…

OpenCV笔记(十五)——使用Laplace算子进行图像的边缘检测

在笔记十四中&#xff0c;我们使用了Sobel算子对图像进行边缘检测&#xff0c;理论依据是像素变化最快的地方最有可能是边缘处&#xff0c;所以使用sobel算子对图像做微分&#xff0c;得到的结果图像当中灰度较大的区域&#xff0c;即为边缘处。 在这里&#xff0c;我们使用Lap…

设计模式之:享元模式FlyweightPattern的实现

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 享元模式的理解&#xff1a; 享元模式的定义&#xff1a;运用共享技术支持大量细粒度对象的复用&#xff1b; Flyweight P…

安全公司笔试面试题总结

一IP地址&#xff08;注意地址范围和私有地址的定义&#xff09; IP地址分为五类&#xff0c;A类保留给政府机构&#xff0c;B类分配给中等规模的公司&#xff0c;C类分配给任何需要的人&#xff0c;D类用于组播&#xff0c;E类用于实验&#xff0c;各类可容纳的地址数目不同。…

团队作业3——需求改进系统设计

Deadline&#xff1a; 2017-4-21 22:00PM&#xff0c;以博客发表日期为准 评分基准: 按时交 - 有分&#xff0c;检查的项目包括后文的四个方面 需求&原型改进系统设计Alpha任务分配计划测试计划晚交 - 0分迟交两周以上 - 倒扣本次作业分数抄袭 - 倒扣本次作业分数需求&…

sed基本用法

sed可以替换给定文本中的字符串&#xff0c;通过正则表达式来实现。 例如 sed s/pattern/replace_string/ file 1、后缀/g意味着sed会替换每一处匹配。但是有时候并不需要替换前N处。有一个选项可以忽略前N处匹配&#xff0c;并从N1处开始匹配。 echo this thisthisthis | s…

Ubuntu安装开发者平台Backstage

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 Ubuntu安装开发者平台Backstage 什么是Backstage? Backstage是一个构建开发者门户的开源平台。通过支持一个集中的软件分…

7.中文输入验证-原生JS

1 <!DOCTYPE html>2 <html>3 <head lang"en">4 <meta charset"UTF-8">5 <title>中文输入验证-原生JS</title>6 </head>7 <body>8 <input type"text" id"num" οnblur&quo…