JavaScript函数参数以及变量声明讨论
来源:互联网 发布:山东黄金历史交易数据 编辑:程序博客网 时间:2024/05/24 05:45
之前在segmentfault回答了一个问题,关于JavaScript函数参数传值还是传引用。可能是受到C++的影响,一开始我得出的结论是:基本类型传值,引用类型传引用。而且解释的时候甚至还谈到了编译时什么子程序调用,保存现场,返回现场等内容。然而很快就被打脸了,因为我自己也发现了貌似不能自圆其说,然后被一位热心得同学指正了,十分感谢。
只是我有点不理解,但是胡乱猜测只是浪费时间而已。一言不合还是得拿出《JS高程》来看看。然后才发现其实上面写的非常清楚:函数参数都是传值的,只是基本类型传的是value,引用类型传的是address。
其实在这个问题中我忽略了一个关键的因素,那就是函数的参数是一个怎么样的存在?其实函数的参数就相当于在函数内部声明的一个临时变量,只是这个临时变量被赋予了外部传递个参数的值(可以使value或address),而函数内对参数的引用首先会扫描函数作用域内是否存在这个变量,然后在查找上一级作用域。也就是函数内部操作的其实只是这个局部变量。
另外一个关键的点就是要弄明白变量声明和赋值的过程。在声明一个引用类型的时候,首先创建一个变量,将这个变量加到作用域中,然后申请内存存放等式右边的值,而这个变量的指针就指向这个值得地址。就完成了变量声明并赋值的过程:
举个例子:
function (){
var obj = { item : 'value' };
}
首先 创建一个变量 obj ,并为其申请内存,只是此时内存为空,然后将其加入到 function 的局部作用域中,然后申请内存存放 { item:‘value ‘} ,假设 { item:‘value’}的存放地址为 #abcdef,然后obj 的指针指向 {。。。 },其实也就是把 {。。。} 的地址值赋值给 obj ,那么 obj 的值就变成了 #abcdef。过程结束。然后函数结束的时候销毁局部变量,回收内存。
其实到这里还有点疑问,那就是在局部作用域 中申请的内存什么时候会被回收什么时候回继续保留下来。举个栗子:
var obj;//global objfunction f(obj1){ //相当于 var obj1 = obj ; obj={item:'value'}; obj1={item:'value change'};}f(obj);alert(obj.item);// "value"
根据上面的描述,输出这个结果是可以理解的,疑问就是为什么 { item:‘value’}所在的内存区域函数结束的时候没有被系统回收而 { item:”value change”} 所在的内存区域则被垃圾回收系统回收了。
答案是 {item:‘value’} 所在的区域已经被加入到全局作用域当中,而后者则只是局部作用域,所以在局部作用域被销毁(函数结束)的时候内存被系统回收了。
由于 obj 是全局变量,而obj的指针指向{item:‘value’},也就是被obj引用了,在系统进行局部作用域内存回收的时候回收标记被清除;而obj1 以及{item:‘value change’}则是都是局部的作用域属性,在作用域被销毁的时候连同它们也一起被销毁了,内存被回收。
Ps:上述内容纯属个人理解,有错之处还望指正。
P.Ps:跟人讨论好处真是挺多的,没想到一个小问题想了这么多。
- JavaScript函数参数以及变量声明讨论
- [Javascript] 函数参数讨论
- javascript中函数声明、变量声明以及变量赋值之间的关系与影响
- JavaScript函数声明前置与变量声明
- JavaScript 函数总体概述(函数声明/参数传递/返回值/加载/变量和作用域/变量声明提升/匿名函数/回调函数)
- JavaScript中函数声明优先于变量声明
- javascript中的函数式声明与变量式声明
- JavaScript函数声明、变量声明及赋值的优先级问题
- javascript的变量声明和函数声明提升
- javascript的变量声明和函数声明提升
- JavaScript中函数声明优先于变量声明
- 关于javascript变量声明、函数声明提升的问题
- JavaScript的数据类型和变量声明以及js的语句
- JavaScript中变量的声明以及如何使用
- JavaScript中变量的声明以及如何使用
- JavaScript中变量的声明以及如何使用
- 函数声明与函数表达式以及立即执行函数的讨论
- C中一种函数声明方式及可变参数函数讨论
- HttpClient批量上传文件(二)AsyncTask+HttpClient
- 关于Golang中database/sql包的学习笔记
- Bad connect ack with firstBadLink as x.x.x.x:50010异常
- 系统构建堆的函数
- ALE IDoc & RFC of SAP
- JavaScript函数参数以及变量声明讨论
- 高德地图的使用简单介绍
- 临时表空间管理
- 我的c学习:if控制语句 求一元二次方程的根
- VxWorks中logMsg与printf的区别
- Golang Web编程的Get和Post请求发送与解析
- 多重背包二进制优化模板分析
- 责任链模式
- 深入理解Java虚拟机--垃圾回收算法