JavaScript学习笔记(四):函数和递归
0 目录
- 函数的声明
- 函数表达式
- 函数的组成形式
- JavaScript不限制参数个数
- 作用域
- 递归
1 函数的声明
函数的声明和变量的声明类似,是使用function关键字后接函数名
function fun(a){
a = a + 2;
return a;
}
上述示例中,fun
是函数名,它后面有一个括号,是用来放参数的;括号里的a
就是函数的参数,它可以被函数内部的代码所使用;结尾的return
是一个关键字,是用来向函数的调用者返回一个值的。
函数的调用方式:若要调用上述的函数,直接输入函数名加括号及参数即可,如fun(2);
,调用的结果就是计算2+2的值,结果返回数字4
2 函数表达式
形如function(){}
的代码就是函数表达式,可用于声明函数,因为这个函数没有函数名,所以也被叫做"匿名表达式",用法如:
var func = function(){
//代码段...
}
这样子声明的函数,调用时的函数名由变量名func
代替,如:func();
3 函数的组成形式
函数一般包含三部分:
- 函数名称(必须要有)
- 参数(可有可无)
- 函数体(必须要有)
其中,参数分为"形参"和"实参","形参"是函数声明时产生的一个局部变量,而"实参"是调用函数时,传给函数的一个实际值
4 JavaScript不限制参数个数
JavaScript的函数的参数,声明时的形参个数和调用时的实参个数可以不一致,如:
function func1(a, b){
//do somethings
}
func1(1, 2, 3); //允许调用时的实参个数比声明时的形参个数多,不会报错
function func2(a, b, c){
//do somethings
}
func2(1, 2); //允许调用时的实参个数比声明时的形参个数少,可能会报错
当实参的个数比形参的个数多时,多出来的实参将被隐式地存储在实参列表里,不会导致报错。关于这个实参列表,后面再介绍。
当实参的个数比形参的个数少时,多出来的形参会被赋值为undefined
,若在函数里面使用了这个赋值为undefined
的形参,则可能会报错。如上述示例中,调用func2时只传入两个参数,而形参c
就没有接受到传值,此时形参c将被赋值为undefined
,若函数里面使用到了形参c
,则可能会报错,如c.toString();
就会报错。
上面提到,当实参的个数比形参的个数多时,多出来的实参将被隐式地存储在实参列表里,这个实参列表是一个隐式的数组,数组名为arguments
,在函数里面可以通过访问arguments数组来使用多出来的实参。arguments数组存放的不仅限于多出来的实参,所有传入函数的实参都会被存放在arguments数组里。代码举例:
//将任意个数的参数求和
function sum(){
var result = 0;
for(var i = 0; i<arguments.length; i++){
result += arguments[i];
}
console.log(result);
}
sum(1, 2, 3, 4, 5, 6, 7, 8, 9); //输出结果为45
实参列表与各参数相映射
修改实参列表arguments里的数值,会导致对应的参数的值发生改变,如
function fn(a){
console.log(a);
arguments[0] = 10;
console.log(a);
}
fn(1);
执行结果为:
1
10
5 作用域
作用域是变量和函数生效的区域,分为全局和局部
在函数里面声明的变量是局部变量,该变量所在函数以外的区域将无法访问该变量
在函数外声明的变量是全局变量,在任何地方都可以访问到,如:
var a = 1; //a在函数外声明,是全局变量
function func1(){
var b = 2; //b在函数内声明,是局部变量
console.log(a, b); //a和b都可以访问到
}
function func2(){
console.log(a); //a是全局变量,可以访问a
console.log(b); //b是func1的局部变量,不能在func2里访问b
}
console.log(b); //b是func1的局部变量,不能在func1函数外访问b
有种特殊的情况,在函数内部没有声明(没有使用var关键字)的变量也是全局变量:
function func(){
a = 1; //变量a未声明就赋值,属于全局变量
}
console.log(a); //在函数外部也可以访问到a
JavaScript 变量生命周期:
JavaScript 变量生命周期在它声明时初始化。
局部变量在函数执行完毕后销毁。
全局变量在页面关闭后销毁。
6 递归
什么是递归?
递归就是某一函数在其内部调用其本身的一种编程方式,通俗地讲就是"我自己调用我自己"
递归有什么作用?
在数学中,求某一数n的阶乘的方法是:
n的阶乘,等于n乘以(n-1)的阶乘,要求出其结果,又要先求出(n-1)的阶乘;
(n-1)的阶乘,等于(n-1)乘以(n-1-1)的阶乘,要求出其结果,又要先求出(n-1-1)的阶乘;
(n-1-1)的阶乘,等于(n-1-1)乘以(n-1-1-1)的阶乘,要求出其结果,又要先求出(n-1-1-1)的阶乘
...
禁止套娃!!!
像求n的阶乘这种问题,就可以使用递归来编程解决
其实递归就像是在玩俄罗斯套娃
在JavaScript中如何使用递归?
就用求n的阶乘来写代码举例:
function mul(n){
if(n == 1){
return 1;
}
return n * mul(n - 1);
}
递归编程技巧
- 找规律,写返回
- 找终值,写出口
递归的优缺点
- 优点:代码简介,符合常人的思维逻辑
- 缺点:空间复杂度高,执行速度慢
关于递归的优秀文章推荐
什么是递归?先了解什么是递归:https://www.cnblogs.com/Pushy/p/8455862.html
JavaScript中的递归:https://www.cnblogs.com/fundebug/p/9922876.html