JS语法中的传递参数,对于初学者是一个非常重要的概念。很多小伙伴在学习“值传递”和“引用传递”时,会有不少烦恼。今天我们就来通过各种姿势全方位剖析JS中的值传递。
本文章将会用10分钟时间无死角的解析JS的传参方式,希望能对您有所帮助。
先说结论,JS只有值传递,没有引用传递。这句话可能会颠覆一些小伙伴的认知,但请先别急,马上你将会赞同我。
EXP:
function fun(x) {
console.log(x);
}
let a = 123;
fun(a);
运行结果;
在fun(a)这个函数调用语句中,实参为a、形参为x,从输出结果来看,可以证明实参a将数值123传给了形参x。
疑问:是否可以通过形参x数值的修改,来改变实参a的值?
EXP:
function fun(x) {
x = 666;
}
let a = 123;
fun(a);
console.log(a);
运行结果:
可以看到实参a的数值并没有因为x的改变而发生变化。是因为值传递的特点决定,咱们接着往下看。
2、值传递的特点:
单向传递,只能将实参的数值传递给形参,不能将形参的值传递给实参。
EXP:
我们希望编写一个交换两个变量数值的函数swap。
function swap(x, y) {
let t;
t = x;
x = y;
y = t;
}
let a = 123;
let b = 456;
swap(a, b);
console.log(a, b);
运行结果:
虽然swap(a, b)被调,但是实参a,b的值并未发生改变。是因为实参a,b与形参x,y在内存中是不同的空间。这里我们引入一个地址的概念。
地址就是内存中的一个编号,等价于我们常说的引用ID(引用ID是优化后的地址)。
可以将内存想象成一栋高楼,那么地址号就是楼房中的某个房间号。
咱们来通过内存模拟一下实参与形参的交换过程。(如下图)假设实参a的地址18,实参b的地址为19。而形参x的地址为20,形参y的地址为21。
那么在swap函数执行完后。形参x和y的值确实进行了交换,但是由于形参与实参是不同的空间,所以形参x,y的改变,是无法影响到实参a,b的。
疑问:有没有其他办法可以通过形参改变实参的数值呢?
有,当传递的实参为引用类型时,可以通过形参改变实参所指向空间的数值。
这句话比较难以理解。别急,下面咱们来讨究这个问题。
let arr = [1, 2];
function swap(arr1) {
let t;
t = arr1[0];
arr1[0] = arr1[1];
arr1[1] = t;
}
swap(arr);
console.log(arr[0], arr[1]);
运行结果:
这次确实交换了arr数组中的arr[0],arr[1]两个元素的值。
原因是引用类型在内存中是由两块空间构成的:
咱们依然用内存模拟应用类型数据在内存中的存储方式,20代表一块空间,18代表一块空间。如图所示,18的空间是真正存储数据的空间(new出来的堆空间),20是存储真正数据所在空间的地址。
而在swap函数调用时,实参arr将数值18(也就是new出来空间的地址)传值给形参arr1。也就意味着他们都指向同一块空间,那么在swap函数中操作arr1就等价于操作arr本身。就好比一个房子,有两把钥匙,任意一把钥匙都能打开房子。所以arr数组的数值就会发生交换。
总结:
let arr1 = [1, 2];
let arr2 = [3, 4];
function swap(arr1, arr2) {
let t;
t = arr1;
arr1 = arr2;
arr2 = t;
}
swap(arr1, arr2);
console.log(arr1, arr2);
陆荣涛前端学习交流Q群858752519
加群备注:CSDN推荐