JavaScript进阶(三) 值传递和引用传递
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了JavaScript进阶(三) 值传递和引用传递,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3637字,纯文字阅读大概需要6分钟。
内容图文
从C语言开始
- void swap1(int a, int b);
- void swap2(int* a, int* b)
这里swap1是不能交换两个数的值的,swap2可以。那为什么呢?有教材会说,第一个是值传递,第二个是引用传递,传递的是指针,所以第二个可以。好吧,这个解释和没说一样,那下面我就来解释一下,调用这两个函数的时候,到底发生了什么,为什么一个可以交换,另一个不可以。为了方便描述,我把这两个函数的调用代码也写出来
- int main() {
- int a = 3;
- int b = 4;
- swap1(a, b); //此时a = 3, b = 4;
- int* pa = &a;
- int* pb = &b; //为了方便解释,增加这两个临时变量,否则直接写swap2(&a, &b)的话,这行代码做的事情太多,不好解释。
- swap2(pa, pb); //此时a = 4, b = 3;
- return 0;
- }
函数的执行是在栈中,下图描述了swap1执行开始和结束的时候,栈中的情况。
回到JS
- function reverse1(array) {
- var temp = [];
- for (var i = array.length - 1; i > -1; i--) {
- temp.push(array[i]);
- }
- array = temp;
- }
- function reverse2(array) {
- var temp = [];
- for (var i = array.length - 1; i > -1; i--) {
- temp.push(array[i]);
- }
- for (var i = 0; i < array.length; i++) {
- array[i] = temp[i]
- }
- }
这两个函数都是先将一个反序完成的数组存储在temp里面,然后赋值给入参array,就是赋值的方式有所不同。这个不同的赋值方式也导致了结果的不同,结果就是reverse1无法完成工作,reverse2可以。为了解答这个问题,我先讲一下JS里面,内存中对象是如何存储的。当一行代码 var temp = [] 被运行的时候,内存中是这样的:
其中蓝色的是栈,黑框的是堆,用来动态分配内存,最右绿色的表示这段堆的起始地址。也就是说当声明一个对象的时候,栈中保存的内容只是一个指针,真正的内容在堆中。以此为基础,我们再来看一下当函数reverse1执行的时候,内存中如何实现的。为方便举例,假设传入的数组为[1,2,3];
上图为执行前,下图为执行后。当函数reverse1执行时,in作为参数传入。传入参数时,类似C语言的引用传递,将地址复制了一份,压栈传到子函数中。所以两个函数中的变量是指向同一个位置的。当reverse1执行时,temp中存储了array的反序,最后一行赋值的时候,你就看到了如下面的图表示的那样,reverse1中的array确实指向了新的反序数组,但是调用者中的局部变量in却丝毫未动。所以导致了reverse1无法完成反序功能。
那么我们再看reverse2. reverse2中的第二个循环逐个给数组的内容复制,其实它操纵的内存空间就是array指向的区域,我们又知道array和in指向了同一个区域,所以in指向的区域也被改变了。
总结一下以上所说的,
- JS中布尔,数字为基本数据类型,是值传递。无法作为引用传递。所以JS中无法实现基本数据类型的swap函数。
- 对象是引用传递。当传递对象给子函数时,传递的是地址。子函数使用这个地址来操作修改传入的对象。但是如果在子函数修改该地址指向的位置时,这个改变将无法作用于调用者。
- 引用传递其实还是值传递,只是传入的值是个地址,并且该地址指向了一段保存了对象数据的内存。这点和C中的引用传递类似。
特别说一下String
- function foo(s) {
- s = "\"" + s + "\""
- }
- var a = 1
- var b = 1
- a == b //true
- a === b //true
- var s1 = "sdf"
- var s2 = "sdf"
- s1 == s2 //true
- s1 === s2 //true
- s3 = new String("sdf")
- s1 === s3 //false
对于数字,估计各位没有疑问吧。那么对于字符串来说,== 比较的是两个字符串的内容,这个应该也没有疑问。那么===呢?并且为什么s1===s2为true,s1===s3为false呢?
原文:http://www.cnblogs.com/smght/p/4368395.html
内容总结
以上是互联网集市为您收集整理的JavaScript进阶(三) 值传递和引用传递全部内容,希望文章能够帮你解决JavaScript进阶(三) 值传递和引用传递所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。