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 相关文章推荐
使用indexOf等在JavaScript的数组中进行元素查找和替换
Sep 18 Javascript
jquery获取元素值的方法(常见的表单元素)
Nov 15 Javascript
Jquery中offset()和position()的区别分析
Feb 05 Javascript
7个有用的jQuery代码片段分享
May 19 Javascript
jQuery实现元素的插入
Feb 27 Javascript
footer定位页面底部(代码分享)
Mar 07 Javascript
Agularjs妙用双向数据绑定实现手风琴效果
May 26 Javascript
JS严格模式知识点总结
Feb 27 Javascript
JavaScript类数组对象转换为数组对象的方法实例分析
Jul 24 Javascript
ES6如何用一句代码实现函数的柯里化
Jan 18 Javascript
JS猜数字游戏实例讲解
Jun 30 Javascript
element中Steps步骤条和Tabs标签页关联的解决
Dec 08 Javascript
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
如何过滤高亮显示非法字符
2006/10/09 PHP
php+ajax实时输入自动搜索匹配的方法
2014/12/26 PHP
php组合排序简单实现方法
2016/10/15 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
2019/11/25 PHP
php屏蔽错误及提示的方法
2020/05/10 PHP
php封装实现钉钉机器人报警接口的示例代码
2020/08/08 PHP
php并发加锁问题分析与设计代码实例讲解
2021/02/26 PHP
硬盘浏览程序,保存成网页格式便可使用
2006/12/03 Javascript
匹配任意字符的正则表达式写法
2010/04/29 Javascript
window.event快达到全浏览器支持了,以后使用就方便了
2011/11/30 Javascript
jQuery实现动画效果的简单实例
2014/01/27 Javascript
JQuery中DOM事件合成用法实例分析
2015/06/13 Javascript
js立即执行函数: (function ( ){})( ) 与 (function ( ){}( )) 有什么区别?
2015/11/18 Javascript
jQuery实现模仿微博下拉滚动条加载数据效果
2015/12/25 Javascript
基于javascript实现图片预加载
2016/01/05 Javascript
简单的JS时钟实例讲解
2016/01/13 Javascript
详解js前端代码异常监控
2017/01/11 Javascript
详解闭包解决jQuery中AJAX的外部变量问题
2017/02/22 Javascript
Angular.Js中ng-include指令的使用与实现
2017/05/07 Javascript
JavaScript实现二维坐标点排序效果
2017/07/18 Javascript
详解利用 Express 托管静态文件的方法
2017/09/18 Javascript
JavaScript Date对象应用实例分享
2017/10/30 Javascript
Vue利用History记录上一页面的数据方法实例
2018/11/02 Javascript
在vue项目中优雅的使用SVG的方法实例详解
2018/12/03 Javascript
微信小程序使用for循环动态渲染页面操作示例
2018/12/25 Javascript
jQuery HTML css()方法与css类实例详解
2020/05/20 jQuery
Vue跨域请求问题解决方案过程解析
2020/08/07 Javascript
Openlayers测量距离与面积的实现方法
2020/09/25 Javascript
[02:47]2018年度DOTA2最佳辅助位选手4号位-完美盛典
2018/12/17 DOTA
Python随机生成均匀分布在单位圆内的点代码示例
2017/11/13 Python
Python进程间通信 multiProcessing Queue队列实现详解
2019/09/23 Python
pycharm Tab键设置成4个空格的操作
2021/02/26 Python
草莓网化妆品加拿大网站:Strawberrynet Canada
2016/09/20 全球购物
2014年电教工作总结
2014/12/19 职场文书
德生TECSUN S-2000使用手册文字版
2022/05/10 无线电
Apache POI操作批量导入MySQL数据库
2022/06/21 Servers