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 相关文章推荐
如何用javascript去掉字符串里的所有空格
Feb 08 Javascript
Js制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法
Aug 08 Javascript
window.print打印指定div实例代码
Dec 13 Javascript
createTextRange()的使用示例含文本框选中部分文字内容
Feb 24 Javascript
基于Jquery+div+css实现弹出登录窗口(代码超简单)
Oct 27 Javascript
Javascript之Date对象详解
Jun 07 Javascript
JavaScript中setTimeout的那些事儿
Nov 14 Javascript
Vue ElementUI之Form表单验证遇到的问题
Aug 21 Javascript
vue cli3.0 引入eslint 结合vscode使用
May 27 Javascript
javascript浅层克隆、深度克隆对比及实例解析
Feb 09 Javascript
如何优雅地取消 JavaScript 异步任务
Mar 22 Javascript
原生js实现移动小球(碰撞检测)
Dec 17 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下过滤HTML代码的函数
2007/12/10 PHP
php实现cc攻击防御和防止快速刷新页面示例
2014/02/13 PHP
PHP父类调用子类方法的代码例子
2014/04/09 PHP
Zend Framework教程之配置文件application.ini解析
2016/03/10 PHP
PHP实现获取url地址中顶级域名的方法示例
2019/06/05 PHP
PHP设计模式之组合模式定义与应用示例
2020/02/01 PHP
图片完美缩放
2006/09/07 Javascript
jquery 获取表单元素里面的值示例代码
2013/07/28 Javascript
判断ie的两种简单方法
2013/08/12 Javascript
javascript动画算法实例分析
2015/07/31 Javascript
Bootstrap多级导航栏(级联导航)的实现代码
2016/03/08 Javascript
VUE重点问题总结
2018/03/19 Javascript
angularJs中orderBy筛选以及filter过滤数据的方法
2018/09/30 Javascript
vue实现修改图片后实时更新
2019/11/14 Javascript
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解
2019/12/07 Javascript
寻找网站后台地址的python脚本
2014/09/01 Python
Python安装第三方库的3种方法
2015/06/21 Python
python爬虫系列Selenium定向爬取虎扑篮球图片详解
2017/11/15 Python
分析Python读取文件时的路径问题
2018/02/11 Python
Python面向对象类的继承实例详解
2018/06/27 Python
python生成密码字典的方法
2018/07/06 Python
Python3单行定义多个变量或赋值方法
2018/07/12 Python
Python 创建新文件时避免覆盖已有的同名文件的解决方法
2018/11/16 Python
python实现合并多个list及合并多个django QuerySet的方法示例
2019/06/11 Python
Python实现TCP探测目标服务路由轨迹的原理与方法详解
2019/09/04 Python
浅谈Python type的使用
2019/11/19 Python
python单向循环链表原理与实现方法示例
2019/12/03 Python
Python接口测试结果集实现封装比较
2020/05/01 Python
PyTorch 导数应用的使用教程
2020/08/31 Python
Unix如何添加新的用户
2014/08/20 面试题
新年寄语大全
2014/04/12 职场文书
吨的认识教学反思
2014/04/27 职场文书
同志主要表现材料
2014/08/21 职场文书
党员学习正风肃纪思想汇报
2014/09/12 职场文书
2016年圣诞节活动总结范文
2016/04/01 职场文书
如何在Mac上通过docker配置PHP开发环境
2021/05/29 PHP