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 相关文章推荐
ext for eclipse插件安装方法
Apr 27 Javascript
JS提交并解析后台返回的XML的代码
Nov 03 Javascript
jQuery 获取/设置/删除DOM元素的属性以a元素为例
May 23 Javascript
JavaScript组件开发完整示例
Dec 15 Javascript
js实现瀑布流的三种方式比较
Jun 28 Javascript
浅谈js的html元素的父节点,子节点
Aug 06 Javascript
Node.js中process模块常用的属性和方法
Dec 13 Javascript
初探Vue3.0 中的一大亮点Proxy的使用
Dec 06 Javascript
开发中常用的25个JavaScript单行代码(小结)
Jun 28 Javascript
Vue 3.x+axios跨域方案的踩坑指南
Jul 04 Javascript
JS中一些高效的魔法运算符总结
May 06 Javascript
JavaScript实现登录窗体
Jun 22 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木马webshell扫描器代码
2012/01/25 PHP
Window下PHP三种运行方式图文详解
2013/06/11 PHP
PHP实现今天是星期几的几种写法
2013/09/26 PHP
php 批量替换html标签的实例代码
2013/11/26 PHP
PHP数字字符串左侧补0、字符串填充和自动补齐的几种方法
2014/05/10 PHP
php实现的九九乘法口诀表简洁版
2014/07/28 PHP
php处理抢购类功能的高并发请求
2018/02/08 PHP
PHP保存Base64图片base64_decode的问题整理
2019/11/04 PHP
Yii-自定义删除确认弹框(zyd)jquery实现代码
2013/03/04 Javascript
浅谈关于JavaScript的语言特性分析
2013/04/11 Javascript
用函数模板,写一个简单高效的 JSON 查询器的方法介绍
2013/04/17 Javascript
jQuery表单域选择器用法分析
2015/02/10 Javascript
JavaScript严格模式详解
2017/01/16 Javascript
NodeJS仿WebApi路由示例
2017/02/28 NodeJs
VueJs单页应用实现微信网页授权及微信分享功能示例
2017/07/26 Javascript
利用three.js画一个3D立体的正方体示例代码
2017/11/19 Javascript
Angular实现点击按钮控制隐藏和显示功能示例
2017/12/29 Javascript
Node.js使用Koa搭建 基础项目
2018/01/08 Javascript
使用webpack3.0配置webpack-dev-server教程
2018/05/29 Javascript
小程序清理本地缓存的方法
2018/08/17 Javascript
Element Notification通知的实现示例
2020/07/27 Javascript
[01:35]2018完美盛典章节片——共竞
2018/12/17 DOTA
浅谈Python 集合(set)类型的操作——并交差
2016/06/30 Python
Python3安装Scrapy的方法步骤
2017/11/23 Python
浅谈django model postgres的json字段编码问题
2018/01/05 Python
Python中对数组集进行按行打乱shuffle的方法
2018/11/08 Python
利用python numpy+matplotlib绘制股票k线图的方法
2019/06/26 Python
python列表切片和嵌套列表取值操作详解
2020/02/27 Python
基于python3.7利用Motor来异步读写Mongodb提高效率(推荐)
2020/04/29 Python
python 写一个性能测试工具(一)
2020/10/24 Python
css3 仿写阿里云水纹效果的示例代码
2018/02/10 HTML / CSS
企业项目策划书
2014/01/11 职场文书
计算机数据库专业职业生涯规划书
2014/02/08 职场文书
政府四风问题整改措施
2014/10/04 职场文书
幼儿园大班教师个人总结
2015/02/05 职场文书
解决MultipartFile.transferTo(dest) 报FileNotFoundExcep的问题
2021/07/01 Java/Android