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 相关文章推荐
JS OOP包机制,类创建的方法定义
Nov 02 Javascript
Javascript 中 null、NaN和undefined的区别总结
Apr 10 Javascript
document.documentElement和document.body区别介绍
Sep 16 Javascript
javascript alert乱码的解决方法
Nov 05 Javascript
js获取时间精确到秒(年月日)
Mar 16 Javascript
jQuery实现弹出带遮罩层的居中浮动窗口效果
Sep 12 Javascript
深入学习 JavaScript中的函数调用
Mar 23 Javascript
Node.js net模块功能及事件监听用法分析
Jan 05 Javascript
基于layui框架响应式布局的一些使用详解
Sep 16 Javascript
react用Redux中央仓库实现一个todolist
Sep 29 Javascript
JS实现可视化音频效果的实例代码
Jan 16 Javascript
js实现列表按字母排序
Aug 11 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
php设计模式 Builder(建造者模式)
2011/06/26 PHP
ThinkPHP让分页保持搜索状态的方法
2014/07/02 PHP
PHP实现批量检测网站是否能够正常打开的方法
2016/08/23 PHP
laravel5.1框架基础之Blade模板继承简单使用方法分析
2019/09/05 PHP
javascript教程之不完整的继承(js原型链)
2014/01/13 Javascript
js监控IE火狐浏览器关闭、刷新、回退、前进事件
2014/07/23 Javascript
jquery获取radio值(单选组radio)
2014/10/16 Javascript
轻松创建nodejs服务器(4):路由
2014/12/18 NodeJs
JS实现隔行换色的表格排序
2017/03/27 Javascript
Angular2学习教程之TemplateRef和ViewContainerRef详解
2017/05/25 Javascript
基于jQuery实现手风琴菜单、层级菜单、置顶菜单、无缝滚动效果
2017/07/20 jQuery
vue.js实现简单轮播图效果
2017/10/10 Javascript
vue js秒转天数小时分钟秒的实例代码
2018/08/08 Javascript
JavaScript链式调用实例浅析
2018/12/19 Javascript
highCharts提示框中显示当前时间的方法
2019/01/18 Javascript
详解vue中router-link标签所必备了解的属性
2019/04/15 Javascript
详解JavaScript实现动态的轮播图效果
2019/04/29 Javascript
详解async/await 异步应用的常用场景
2019/05/13 Javascript
Vue中fragment.js使用方法小结
2020/02/17 Javascript
js实现石头剪刀布游戏
2020/10/11 Javascript
[01:04]DOTA2上海特锦赛现场采访 FreeAgain遭众解说围攻
2016/03/25 DOTA
[01:31:02]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第一场
2019/08/22 DOTA
python snownlp情感分析简易demo(分享)
2017/06/04 Python
numpy使用技巧之数组过滤实例代码
2018/02/03 Python
Python中浅拷贝copy与深拷贝deepcopy的简单理解
2018/10/26 Python
python实现dijkstra最短路由算法
2019/01/17 Python
python爬虫之爬取百度音乐的实现方法
2019/08/24 Python
python实现的多任务版udp聊天器功能案例
2019/11/13 Python
sklearn和keras的数据切分与交叉验证的实例详解
2020/06/19 Python
基于Django集成CAS实现流程详解
2020/11/28 Python
blueseventy官网:铁人三项和比赛泳衣
2021/02/06 全球购物
大学校庆邀请函
2014/01/11 职场文书
交通志愿者活动总结
2014/06/27 职场文书
2014司机年终工作总结
2014/12/05 职场文书
2015年“世界无车日”活动方案
2015/05/06 职场文书
速龙x4-860k处理器相当于i几
2022/04/20 数码科技