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 相关文章推荐
(currentStyle)javascript为何有时用style得不到已设定的CSS的属性
Aug 15 Javascript
图片连续滚动代码[兼容IE/firefox]
Jun 11 Javascript
Prototype源码浅析 Number部分
Jan 16 Javascript
多次注册事件会导致一个事件被触发多次的解决方法
Aug 12 Javascript
javascript设计模式之解释器模式详解
Jun 05 Javascript
JQuery中serialize() 序列化
Mar 13 Javascript
TypeScript 中接口详解
Jun 19 Javascript
jquery获取select选中值的文本,并赋值给另一个输入框的方法
Aug 21 jQuery
SSM+layUI 根据登录信息显示不同的页面方法
Sep 20 Javascript
jQuery操作选中select下拉框的值代码实例
Feb 07 jQuery
react antd表格中渲染一张或多张图片的实例
Oct 28 Javascript
Vue中foreach数组与js中遍历数组的写法说明
Jun 05 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水印
2007/03/16 PHP
PHP间隔一段时间执行代码的方法
2014/12/02 PHP
php通过正则表达式记取数据来读取xml的方法
2015/03/09 PHP
php+redis实现多台服务器内网存储session并读取示例
2017/01/12 PHP
javascript和jquery修改a标签的href属性
2013/12/16 Javascript
Javascript中引用示例介绍
2014/02/21 Javascript
分享一则JavaScript滚动条插件源码
2015/03/03 Javascript
javascript中slice(),splice(),split(),substring(),substr()使用方法
2015/03/13 Javascript
基于jquery实现日历签到功能
2020/09/11 Javascript
JS验证逗号隔开可以是中文字母数字
2016/04/22 Javascript
利用Angularjs和原生JS分别实现动态效果的输入框
2016/09/01 Javascript
Bootstrap的popover(弹出框)在append后弹不出(失效)
2017/02/27 Javascript
在Vue中使用echarts的实例代码(3种图)
2017/07/10 Javascript
详解jQuery同步Ajax带来的UI线程阻塞问题及解决办法
2017/08/09 jQuery
深入理解Vue生命周期、手动挂载及挂载子组件
2017/09/27 Javascript
基于JS实现简单滑块拼图游戏
2019/10/12 Javascript
Python 专题六 局部变量、全局变量global、导入模块变量
2017/03/20 Python
Python实现读写sqlite3数据库并将统计数据写入Excel的方法示例
2017/08/07 Python
TensorFlow安装及jupyter notebook配置方法
2017/09/08 Python
用python实现将数组元素按从小到大的顺序排列方法
2018/07/02 Python
Python使用combinations实现排列组合的方法
2018/11/13 Python
python列表每个元素同增同减和列表元素去空格的实例
2019/07/20 Python
详解Python并发编程之创建多线程的几种方法
2019/08/23 Python
Python之数据序列化(json、pickle、shelve)详解
2019/08/30 Python
详谈tensorflow gfile文件的用法
2020/02/05 Python
python多线程和多进程关系详解
2020/12/14 Python
python+opencv3.4.0 实现HOG+SVM行人检测的示例代码
2021/01/28 Python
Python中Qslider控件实操详解
2021/02/20 Python
实习鉴定评语
2014/01/19 职场文书
《夸父追日》教学反思
2014/02/26 职场文书
社区文化建设方案
2014/05/02 职场文书
2015年百日安全活动总结
2015/03/26 职场文书
公司员工手册范本
2015/05/14 职场文书
焦裕禄纪念馆观后感
2015/06/09 职场文书
jquery插件实现搜索历史
2021/04/24 jQuery
PHP实现rar解压读取扩展包小结
2021/06/03 PHP