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实用技巧(一)
Aug 16 Javascript
浅谈javascript的原型继承
Jul 25 Javascript
JavaScript中判断整字类型最简洁的实现方法
Nov 08 Javascript
jquery+css实现的红色线条横向二级菜单效果
Aug 22 Javascript
js拖拽的原型声明和用法总结
Apr 04 Javascript
node.js实现端口转发
Apr 14 Javascript
vue实现移动端图片裁剪上传功能
Aug 18 Javascript
动手写一个angular版本的Message组件的方法
Dec 16 Javascript
vuex 动态注册方法 registerModule的实现
Jul 03 Javascript
LayUI数据接口返回实体封装的例子
Sep 12 Javascript
使用JavaScript获取扫码枪扫描得到的条形码的思路代码详解
Jun 10 Javascript
vue实现整屏滚动切换
Jun 29 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使用FFmpeg接口获取视频的播放时长、码率、缩略图以及创建时间
2016/11/07 PHP
laravel 多图上传及图片的存储例子
2019/10/14 PHP
js时间日期和毫秒的相互转换
2013/02/22 Javascript
如何用JavaScript动态呼叫函数(两种方式)
2013/05/03 Javascript
js数组去重的常用方法总结
2014/01/24 Javascript
js中数组排序sort方法的原理分析
2014/11/20 Javascript
node.js中的fs.fchmodSync方法使用说明
2014/12/16 Javascript
AngularJS上拉加载问题解决方法
2016/05/23 Javascript
jQuery插件zTree实现获取当前选中节点在同级节点中序号的方法
2017/03/08 Javascript
微信小程序--onShareAppMessage分享参数用处(页面分享)
2017/04/18 Javascript
使用vue框架 Ajax获取数据列表并用BootStrap显示出来
2017/04/24 Javascript
微信小程序图片选择、上传到服务器、预览(PHP)实现实例
2017/05/11 Javascript
微信小程序 Buffer缓冲区的详解
2017/07/06 Javascript
Vue组件模板形式实现对象数组数据循环为树形结构(实例代码)
2017/07/31 Javascript
Angular4的输入属性与输出属性实例详解
2017/11/29 Javascript
laravel5.3 vue 实现收藏夹功能实例详解
2018/01/21 Javascript
JavaScript ECMA-262-3 深入解析(一):执行上下文实例分析
2020/04/25 Javascript
Python的装饰器用法学习笔记
2016/06/24 Python
django请求返回不同的类型图片json,xml,html的实例
2018/05/22 Python
Django 内置权限扩展案例详解
2019/03/04 Python
详解python读取和输出到txt
2019/03/29 Python
如何分离django中的媒体、静态文件和网页
2019/11/12 Python
Tensorflow tf.dynamic_partition矩阵拆分示例(Python3)
2020/02/07 Python
Python之关于类变量的两种赋值区别详解
2020/03/12 Python
如何在sublime编辑器中安装python
2020/05/20 Python
Django之富文本(获取内容,设置内容方式)
2020/05/21 Python
浅谈keras中的Merge层(实现层的相加、相减、相乘实例)
2020/05/23 Python
Python爬虫破解登陆哔哩哔哩的方法
2020/11/17 Python
飞利浦法国官网:Philips法国
2019/07/10 全球购物
美国在线医疗分销商:MedEx Supply
2020/02/04 全球购物
Java的类与C++的类有什么不同
2014/01/18 面试题
解除劳动合同协议书范本
2014/04/14 职场文书
三字经教学反思
2014/04/26 职场文书
教师廉政准则心得体会
2016/01/20 职场文书
多人股份制合作协议书
2016/03/19 职场文书
WinServer2012搭建DNS服务器的方法步骤
2022/06/10 Servers