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 相关文章推荐
ExtJS DOM元素操作经验分享
Aug 28 Javascript
js数组转json并在后台对其解析具体实现
Nov 20 Javascript
jquery ztree实现下拉树形框使用到了json数据
May 14 Javascript
js中日期的加减法
May 06 Javascript
Bootstrap入门书籍之(零)Bootstrap简介
Feb 17 Javascript
js HTML5 Canvas绘制转盘抽奖
Sep 13 Javascript
利用浮层使select不可选的实现方法
Dec 03 Javascript
详解本地Node.js服务器作为api服务器的解决办法
Feb 28 Javascript
React如何避免重渲染
Apr 10 Javascript
详解vue添加删除元素的方法
Jun 30 Javascript
vue项目打包上传github并制作预览链接(pages)
Apr 19 Javascript
vue 数字翻牌器动态加载数据
Apr 20 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
php自定义函数实现二维数组按指定key排序的方法
2016/09/29 PHP
PDO::exec讲解
2019/01/28 PHP
jQuery+CSS 实现的超Sexy下拉菜单
2010/01/17 Javascript
JavaScript CSS 修改学习第四章 透明度设置
2010/02/19 Javascript
javascript编码的几个方法详细介绍
2013/01/06 Javascript
jQuery实现鼠标滑过链接控制图片的滑动展开与隐藏效果
2015/10/28 Javascript
JavaScript String 对象常用方法详解
2016/05/13 Javascript
全面解析Bootstrap中form、navbar的使用方法
2016/05/30 Javascript
javaScript事件学习小结(四)event的公共成员(属性和方法)
2016/06/09 Javascript
移动端点击图片放大特效PhotoSwipe.js插件实现
2016/08/25 Javascript
Bootstrap table的使用方法
2016/11/02 Javascript
Bootstrap框架实现广告轮播效果
2016/11/28 Javascript
浅谈vue-cli 3.0.x 初体验
2018/04/11 Javascript
小程序自定义组件实现城市选择功能
2018/07/18 Javascript
Python实现批量下载图片的方法
2015/07/08 Python
Python实现将HTML转换成doc格式文件的方法示例
2017/11/20 Python
理论讲解python多进程并发编程
2018/02/09 Python
Python3实现的字典遍历操作详解
2018/04/18 Python
python使用代理ip访问网站的实例
2018/05/07 Python
Python中的取模运算方法
2018/11/10 Python
python2.7实现邮件发送功能
2018/12/12 Python
python使用writerows写csv文件产生多余空行的处理方法
2019/08/01 Python
Pyinstaller 打包exe教程及问题解决
2019/08/16 Python
python随机生成库faker库api实例详解
2019/11/28 Python
Python中常用的高阶函数实例详解
2020/02/21 Python
Python利用for循环打印星号三角形的案例
2020/04/12 Python
Python 读取位于包中的数据文件
2020/08/07 Python
在Pycharm中安装Pandas库方法(简单易懂)
2021/02/20 Python
春节联欢会主持词
2014/03/24 职场文书
《彭德怀和他的大黑骡子》教学反思
2014/04/12 职场文书
2015小学语文教师个人工作总结
2015/05/20 职场文书
单位工作证明范本
2015/06/15 职场文书
《小小的船》教学反思
2016/02/18 职场文书
详解非极大值抑制算法之Python实现
2021/06/28 Python
Python re.sub 反向引用的实现
2021/07/07 Python
Python常遇到的错误和异常
2021/11/02 Python