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 相关文章推荐
jquery动态调整div大小使其宽度始终为浏览器宽度
Jun 06 Javascript
jquery实现上下左右滑动的方法
Feb 09 Javascript
js判断空对象的实例(超简单)
Jul 26 Javascript
jQuery中table数据的值拷贝和拆分
Mar 19 Javascript
jquery.form.js异步提交表单详解
Apr 25 jQuery
基于jQuery封装的分页组件
Jun 26 jQuery
JavaScript事件方法(实例讲解)
Jun 27 Javascript
微信小程序实现获取小程序码和二维码java接口开发
Mar 29 Javascript
详解jQuery中的prop()使用方法
Jan 05 jQuery
Vue解析剪切板图片并实现发送功能
Feb 04 Javascript
javascript实现获取中文汉字拼音首字母
May 19 Javascript
VUE异步更新DOM - 用$nextTick解决DOM视图的问题
Nov 06 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将fileterms函数返回的结果变成可读的形式
2011/04/21 PHP
PHP 防注入函数(格式化数据)
2011/08/08 PHP
php查看网页源代码的方法
2015/03/13 PHP
PHP Hash算法:Times33算法代码实例
2015/05/13 PHP
javascript RadioButtonList获取选中值
2009/04/09 Javascript
有道JavaScript监听浏览器的问题
2010/06/23 Javascript
YUI Compressor压缩JavaScript原理及微优化
2013/01/07 Javascript
Javascript实现图片不间断滚动的代码
2016/06/22 Javascript
jQuery实现简单的网页换肤效果示例
2016/09/18 Javascript
基于JavaScript实现类名的添加与移除
2017/04/23 Javascript
如何使用JS在HTML中自定义字符串格式化
2017/07/20 Javascript
Angular移动端页面input无法输入的解决方法
2017/11/14 Javascript
JavaScript键盘事件常见用法实例分析
2019/01/03 Javascript
微信小程序利用swiper+css实现购物车商品删除功能
2019/03/06 Javascript
vue+Element实现搜索关键字高亮功能
2019/05/28 Javascript
JS学习笔记之闭包小案例分析
2019/05/29 Javascript
Vuex实现数据增加和删除功能
2019/11/11 Javascript
JS函数本身的作用域实例分析
2020/03/16 Javascript
easyUI 实现的后台分页与前台显示功能示例
2020/06/01 Javascript
[55:47]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第三局
2016/02/27 DOTA
Python常见加密模块用法分析【MD5,sha,crypt模块】
2017/05/24 Python
Python算法输出1-9数组形成的结果为100的所有运算式
2017/11/03 Python
详解Python使用tensorflow入门指南
2018/02/09 Python
python中实现控制小数点位数的方法
2019/01/24 Python
Python Django 简单分页的实现代码解析
2019/08/21 Python
Python全栈之列表数据类型详解
2019/10/01 Python
python GUI库图形界面开发之PyQt5单选按钮控件QRadioButton详细使用方法与实例
2020/02/28 Python
Python3.8安装Pygame教程步骤详解
2020/08/14 Python
分厂厂长岗位职责
2013/12/29 职场文书
《姥姥的剪纸》教学反思
2014/02/25 职场文书
大学开学计划书
2014/04/30 职场文书
2014年销售工作总结
2014/12/01 职场文书
广告公司文案策划岗位职责
2015/04/14 职场文书
检讨书怎么写?
2019/06/21 职场文书
Spring Boot 实现敏感词及特殊字符过滤处理
2021/06/29 Java/Android
Java实现经典游戏泡泡堂的示例代码
2022/04/04 Java/Android