JS - 函数传参 (基础总结)

1、简介
本文介绍了js中函数传参问题。属于基础内容。
你可以先检查看下如下练习题,如果很轻易就可以完成,就不必往下看啦。
2、练习题
以下有6道题。
题1

var a = [1]; var b = a; b = [10] console.info(a) console.info(b)

题2
var a = [1]; var b = a; b[1] = 10 console.info(a) console.info(b)

题3
var a = [1]; function f(a){ a = [10] } f(a); console.info(a)

题4
var a = 1; function f(a){ a = 10 } f(a); console.info(a)

题5
var a = [1]; function f(a){ a[1] = 10 } f(a); console.info(a)

题6
var a = [1]; function f(a){ a[1] = 10 a = 3; } f(a); console.info(a)

答案:
题1: a:[1], b: [10]题2: a:[1,10], b: [1,10]题3: a:[1]题4: a: 1题5: a: [1,10]题6: a: [1,10]

3、内容
1.数据的保存方式
2.赋值运算符的含义
3.参数传递的本质
4.例题讲解
4、数据的保存方式
js中的数据类型分成两大类:基本数据类型和引用数据类型。不论是何种数据类型都需要有一个地方把数据的内容保存下来,在我们给变量赋值的过程中,就是在做保存的过程。
在如下两行代码中,我们分别把一个基本数据类型的数据和引用类型的数据保存在两个变量中,
var a = [10]; var b = 1;

我们先回顾数据保存的方式:
基本数据类型的类型保存在栈区;
引用数据类型的数据要用到两个区域:在栈区保存的是一个地址信息,而在堆区保存着真正的数据,这个堆区的地址就在栈区中保存着。
5、赋值运算符的含义
赋值运算符是我们最常用的运算符:= 。 当我们在写一个赋值运算符时,其实背后的工作还是很多的。以如下:
5.1、右边是值
varName = value;

它表示把等号右边的值保存到等号左边的变量(或者是常量)中。
背后做的事有:
检查等号左边的这个变量是否存在。如果不存在,是否允许创建这个变量。这一步没有问题了,再去看右边。
把右边的值找个地方存起来,此时就要根据右边的值是引用类型还是基本数据类型来决定如何去保存它了,如果是基本数据类型,则直接保存在栈区;如果是引用类型,则先在堆区中保存数据,再把地址保存在栈区。
5.2、右边是变量
varName = var1;

【JS - 函数传参 (基础总结)】它表示把等号右边的变量中保存的值赋值到等号左边的变量(或者是常量)中。是直接把栈区中的保存的内容进行赋值。
5.3、例子 我们接着上面的代码来:
var a = [1]; var b = a; // 注意这一句

给通过下标给b赋值
var a = [1]; var b = a; b[1] = 10; // 把10保存在第二个元素中。

结果如下:
a:[1,10], b: [1,10]
var a = [1]; var b = a; b[1] = 10; b = [10]; // 把数级保存在b中

6、函数中的参数传递
6.1、本质 在函数的调用过程中,存在传值的过程 具体来说,是实参的值传给形参。
我们可以这样来理解这个过程:
函数的形参就是函数内部定义的局部变量。
实参传递给形参的过程就是一个赋值过程。
函数调用结束后,局部变量会被回收。
6.2、例子 下面来看一个例子
var a = [1]; function f(a){ a[1] = 10 a = [10] } f(a); console.info(a)

我将分步骤来讲解这个过程。
初始情况下:
在调用f(a)时,相当于是做了一次赋值操作:把全局变量a的值赋值给局部变量a(赋值的内部是栈中的内容)。结果是它们指一个数组。
下面执行函数体中的第一句:
下面执行函数体中的第二句
最后一步:
函数调用结束,释放函数中的变量及对应的空间。
函数调用完毕,释放空间。局部变量a,及f-堆中的数组全回收了。此时访问的a是全局变量。
7、总结
基本数据类型只需要用到栈区;引用数据类型需要用到栈区和堆区;
赋值是把右边的值保存到左边的变量中;赋值的过程中传递的栈区的内容;
函数中的形参相当于函数内部的局部变量 ;实参传给形参的过程就是赋值的过程;
函数调用完成后,它的局部变量会随之销毁,除非遇到特殊情况(例如闭包)

    推荐阅读