javascript中的变量是传值还是传址的?


Posted in Javascript onApril 19, 2010

这个标题念起来有点拗口,但却是理解数据结构的关键。标题中的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函数时,第一个参数传递的是实际的字符串值,第二参数传递的是对象的引用(内存地址)。

Javascript 相关文章推荐
jQuery点击弹出下拉菜单的小例子
Aug 01 Javascript
JS教程:window.location使用方法的区别介绍
Oct 04 Javascript
jQuery实现tag便签去重效果的方法
Jan 20 Javascript
js实现iGoogleDivDrag模块拖动层拖动特效的方法
Mar 04 Javascript
jQuery中借助deferred来请求及判断AJAX加载的实例讲解
May 24 Javascript
微信小程序 Audio API详解及实例代码
Sep 30 Javascript
浅谈js for循环输出i为同一值的问题
Mar 01 Javascript
AngularJS实现页面定时刷新
Mar 14 Javascript
gulp解决跨域的配置文件问题
Jun 08 Javascript
React 全自动数据表格组件——BodeGrid的实现思路
Jun 12 Javascript
Nuxt配置Element-UI按需引入的操作方法
Jul 06 Javascript
vue3如何优雅的实现移动端登录注册模块
Mar 29 Vue.js
js获取当前select 元素值的代码
Apr 19 #Javascript
监控 url fragment变化的js代码
Apr 19 #Javascript
jquery获取input表单值的代码
Apr 19 #Javascript
编写高性能的JavaScript 脚本的加载与执行
Apr 19 #Javascript
jquery 关键字“拖曳搜索”之“拖曳”以及 图片“提示自适应放大”效果 的实现
Apr 18 #Javascript
jquery 新手学习常见问题解决方法
Apr 18 #Javascript
javascript 设计模式之单体模式 面向对象学习基础
Apr 18 #Javascript
You might like
冰滴咖啡制作步骤
2021/03/03 冲泡冲煮
PHP获取表单textarea数据中的换行问题
2010/09/10 PHP
解析CodeIgniter自定义配置文件
2013/06/18 PHP
php输出指定时间以前时间格式的方法
2015/03/21 PHP
如何使用jQuery+PHP+MySQL来实现一个在线测试项目
2015/04/26 PHP
非常好的js代码
2006/06/27 Javascript
超级退弹代码
2008/07/07 Javascript
Jquery Ajax学习实例6 向WebService发出请求,返回DataSet(XML) 异步调用
2010/03/18 Javascript
poshytip 基于jquery的 插件 主要用于显示微博人的图像和鼠标提示等
2012/10/12 Javascript
动态加载iframe时get请求传递中文参数乱码解决方法
2014/05/07 Javascript
七个很有意思的PHP函数
2014/05/12 Javascript
JavaScript基础知识学习笔记
2014/12/02 Javascript
JavaScript中的some()方法使用详解
2015/06/09 Javascript
AngularJS 表达式详细讲解及实例代码
2016/07/26 Javascript
JavaScript使用键盘输入控制实现数字验证功能
2016/08/19 Javascript
JavaScript每天必学之数组和对象部分
2016/09/17 Javascript
JS正则匹配URL网址的方法(可匹配www,http开头的一切网址)
2017/01/06 Javascript
JS加密插件CryptoJS实现AES加密操作示例
2018/08/16 Javascript
详解如何在vue项目中使用lodop打印插件
2018/09/27 Javascript
js实现倒计时器自定义时间和暂停
2019/02/25 Javascript
Vuex新手的理解与使用详解
2019/05/31 Javascript
浅谈vue项目用到的mock数据接口的两种方式
2019/10/09 Javascript
Vue Router 实现动态路由和常见问题及解决方法
2020/03/06 Javascript
详细分析Node.js 模块系统
2020/06/28 Javascript
创建与框架无关的JavaScript插件
2020/12/01 Javascript
Python 硬币兑换问题
2019/07/29 Python
澳大利亚网上买书:Angus & Robertson
2019/07/21 全球购物
美国手机支架公司:PopSockets
2019/11/27 全球购物
天游软件面试
2013/11/23 面试题
十佳青年事迹材料
2014/08/21 职场文书
2014年社区妇联工作总结
2014/12/02 职场文书
转学证明范本
2015/06/19 职场文书
学校学期工作总结
2015/08/13 职场文书
村党总支部公开承诺书2016
2016/03/25 职场文书
Golang生成Excel文档的方法步骤
2021/06/09 Golang
Python可视化学习之seaborn调色盘
2022/02/24 Python