javascript中的变量是传值还是传址的?
发布时间:2024-04-10 10:52:28
这个标题念起来有点拗口,但却是理解数据结构的关键。标题中的4个术语,对应的英文分别是:shallow copy(注意,不是shadow copy)、deep copy、pass by value、pass by reference(或pass by address)。传址和传引用是一回事。
一门编程语言的核心是数据结构,粗略来讲,可以把数据结构分成不可变类型(immutable)和可变类型(mutable)。为什么这么分呢?这涉及到内存分配问题。对于不可变类型,只要分配有限的内存空间即可,而对于不可变类型,理论上则要分配没有大小限制的空间。因此,这么分是出于合理利用系统资源的考虑。实际上,堆内存和栈内存分别用于保存不可变类型值和可变类型值。
什么是不可变类型?就是该值一旦赋予某个变量,就只属于某个变量,不能同属于其他变量。如:
window.onload=function()
{
var stringValue = "淡淡的";
var anotherStringValue = stringValue;
stringValue = "I have changed";
alert(stringValue);// 输出 I have changed
alert(anotherStringValue);// 输出 淡淡的
此时,anotherStringValue中保存的值会不会也变成“I have changed”?不会。因为
var anotherStringValue = stringValue;
照stringValue中保存的字符串的原样,复制一个字符串(相应地,在内存中分配一块新空间),并将该字符串赋给anotherStringValue。换句话说,这两个变量虽然保存的值相同,但它们的值并不在一块内存中。因此,修改任何一个变量,都不会影响另一个变量。即
stringValue = “I have changed”;
只会影响stringValue的值。但是,确切来讲,stringValue = “I have changed”;并不是修改stringValue,而是创建了一个新字符串(相应地,在内存中分配一块新空间),然后让stringValue引用该字符串——更像是替换变量的值;原来的字符串呢?因为没有变量引用它,也就成为垃圾了(当然,垃圾所占用的内存会被回收)。
由此可见,赋值操作对于不变类型而言,传递的是内存中的值本身。那么,对于可变类型呢?当然,传递的是内存中值的引用(或者说地址),而且无论传递多少次,内存中始终都只有一份原始值——毕竟可变类型大小莫测,只保存一份原始值能最大限度节省内存空间。例如:
window.onload=function()
{
var objectValue = {1:1,'s':'string','innerObject':{'innerArray' : [1,2,3]}};
var anotherObjectValue = objectValue;
objectValue[1] = 100;
alert(anotherObjectValue[1]); //输出 100
}
不言自明,这里的anotherObjectValue通过赋值操作,从objectValue那里只获得了对原始对象( {1:1,'s':'string','innerObject':{'innerArray' : [1,2,3]}})的引用,也就是该对象在内存中的地址,或者说“门牌号码”。因此,通过objectValue修改原始对象的第一个元素(objectValue[1] = 100;),结果同样会在anotherObjectValue[1]那里得到反映——因为这两个变量共享同一份原始值。
在JavaScript中,给函数传递参数是按照上述默认约定——即对不可变类型,传值;对可变类型,传址——进行的。如:
function example(str, obj){
……
}
example(stringValue,objectValue);
调用example函数时,第一个参数传递的是实际的字符串值,第二参数传递的是对象的引用(内存地址)。
猜你喜欢
- requests 是一个非常小巧全面的库,应用它可以很容易写出与服务器进行交互的程序,今天遇到了一个问题,与服务器交互时,url都是http
- 随着SaaS服务的流行,越来越多的人选择在各个平台上编写文档,制作表格并进行分享。同时,随着Markdown语法的破圈,很多平台开始集成支持
- 直接奔入主题看下面pywebio程序,实现了Python的简陋在线编辑器from pywebio.input import *from py
- 文中给大家介绍MySQL 字符串截取相关函数,具体内容如下所示:在工作中,可能需要将某些字段按某个分割符组成一个字符串作为字段值存取到数据库
- 代码如下:ALTER function [dbo].[GetOrderNum]( @ebaystockflag varchar(20)//规
- 我们利用linux系统中yum安装Apache+MySQL+PHP是非常的简单哦,只需要几步就可以完成,具体如下:一、脚本YUM源安装:1.
- 前言range函数可创建一个整数列表。如果需要知道当前元素在列表中的索引,推荐用enumerate代替range。zip函数用于同时遍历多个
- 1、安装requests、xlrd、json、unittest库<1>pip 命令安装:pip install requests
- 操作方法如下所示:File-->Settings-->Editor-->Color&Fonts-->Lang
- 目录一.准备工作二.预览1.启动2.添加城市3.展示多个城市天气三.设计流程1.获取城市天气信息过程四.源代码1.Weather_Tool-
- 前言:Requests简介Requests 是使用Apache2 Licensed 许可证的 HTTP 库。用 Python 编写,真正的为
- 耦合两个或以上的体系或两种运动形式间相互作用而彼此影响以至于联合起来的现象。在软件工程中,对象之间的耦合度就是对象之间的依赖性,对象之间的耦
- bbssend.asp'寻呼台页面,向在线网友发送寻呼信息<%@ Language=VBScript %&
- 我就废话不多说了,直接上代码吧!import turtlet=turtle.Turtle()turtle.Turtle().screen.d
- 打开终端输入以下命令 --> 回车 -->输入密码 -->回车 -->结束:sudo rm -rf /usr/loc
- 1.连接测试连接是否成功:import redisr = redis.Redis(host='192.168.136.102'
- MySQL的Explain命令用于查看执行效果。虽然这个命令只能搭配select类型语句使用,如果你想查看update,delete类型语句
- 最近项目中使用了vue-router的addRoutes这个api,遇到了一个小坑,记录总结一下。场景复现:做前端开发的同学,大多都遇到过这
- 一、在搭建的时候参考以下文章http://www.cnblogs.com/zsy/archive/2016/02/28/5223957.ht
- 要真说出来哪一个函数能够做得到,还真难。但我们可用下面的代码来进行识别,返回“假”即偶数,返回“真”则奇数: function&n