关于Js中函数传参是引用还是传值

xiaoxiao2021-02-28  86

写在前面: 本文是参考了网上的一些资料后,根据自己的理解整理出来的,并非完全原创。本文主要目的是对本人学习情况进行记录,能帮到别人就更好。如有错漏之处,希望不吝赐教~

正文: 提到如题内容,就不得不提一下变量。在Js中,变量就分俩阵营,基础类型和引用类型。 基础类型包括:undefined, Null, Number, Boolean, String这五虎上将; 引用类型其实是个光杆儿司令,就一个: Object(多汁,哦不对,是多值)。 这俩阵营在使用上有一点点区别,基础类型在赋值时是重新分配内存空间,而引用行变量则是将内存地址拿出来。其实很简单,举个例子就一丝不挂了。

//例1-基础类型: var a = 1; var b = a; a = 2; console.log(a);//2 console.log(b);//1 //例2-引用类型: var obj1 = new Object(); obj1.a = 1; var obj2 = obj1; obj2.a = 2; console.log(obj1.a);//2 console.log(obj2.a);//2

例1,a起初等于1,将a赋值给b,此时b的值也就是1。将a的值改为2,然后分别打印a,b。 结果a=2,b=1可以看出,在b赋值后,a改变了原来的值,但并没有影响到b。 例2与例1的思路是一样的,就是将obj1赋值给obj2,然后改变两者中一个的值,查看对另一个变量是否有影响。结果发现,改变了obj2之后,obj1也跟着改变了。

下面继续看函数中传递参数,究竟是引用还是传值呢?举个例子~

//例3-基础类型变量作为参数: function setName (name) { name = 'Allen ' + name; return name; } var tempName1 = 'Iverson'; var tempName2 = setName(tempName1); console.log(tempName1);//Iverson console.log(tempName2);//Allen Iverson

由例3看出,基础变量作为参数时,函数是按值传递参数的。

//例4-引用类型变量作为参数: function setName (obj) { obj.name = 'Allen'; return obj; } var obj1 = new Object(); obj1.name = 'Iverson'; var obj2 = setName(obj1); console.log(obj1.name);//Allen console.log(obj2.name);//Allen

(由于Js不能打印内存地址,所以嘛,对于这种涉及到引用的问题就比较烦……不方便!) 由例4可以看出,咱们传了一个对象(引用类型)进去,然后原本叫Iverson的就改名叫Allen了(setName这小子,下手太快了,刚给它个对象,立马就给改名了……)这……是不是就意味着当传一个引用类型变量进去,函数传参规则就改变了呢?

//例5-引用类型变量作为参数-到底是传了内存地址还是直接使用了obj1本身?: function setName (obj) { obj.name = 'Allen'; obj = new Object();//我改变一下内存地址试试 obj.name = 'Allen Iverson'; return obj; } var obj1 = new Object(); obj1.name = 'Iverson'; var obj2 = setName(obj1); console.log(obj1.name);//Allen console.log(obj2.name);//Allen Iverson

嗯?这是怎么个意思 ?我改个内存地址,这obj1就不变了! 这个现象应该是说:当我把obj1传进去的时候,其实传的就是它的内存地址而已,并不是obj1本身。那么在刚进入setName函数时,其中的obj其实就是一个与obj1拥有相同内存地址的变量,当改变obj.name时,其实是在改变obj1的内存中存放的内容,所以obj1变成了Allen。但是当obj重新分配地址(new Object())后,obj的内存地址就与obj1的内存地址不同了,那么我再改变obj.name时,这时跟obj1一毛钱关系都没有了!而函数返回的是新的内存了,所以承接函数返回值的obj2变成了Allen Iverson。

也就是说,其实当引用类型的变量被当作参数传递的时候,传递的是内存地址这个值。这样说来,函数传递参数就是按值传递的。

举了5个栗子,一步一步的剥掉了函数虚伪的伪装,最后一丝不挂的函数告诉咱们:老子就是按值传递的, 爱咋咋地吧!!!

结尾: 虽然在写这篇文之初,觉得自己已经理解了这个问题,但是随着字数的不断增加,发展到后面,发现自己还是理解的并不透彻,可能以后还会继续这个话题,不过目前到此为止了。有些问题就是这样的,需要一遍一遍的想。理解了一次的问题,不代表彻底理解,过段时间重新思考的时候可能还会发现新的东西。

转载请注明原文地址: https://www.6miu.com/read-76561.html

最新回复(0)