这是我参与更文挑战的第12天,活动详情查看: 更文挑战
嵌套与递归
嵌套函数与作用域链
首先我们来看什么是嵌套函数。
嵌套函数就是在一个函数内部定义另一个函数。
知道了什么是嵌套函数,那什么是作用域链呢?
在内层函数执行过程中可能会用到外部函数的变量,这时内层函数首先会在当前函数内找这个变量,如果找不到则在外层函数中继续找该变量,如果让找不到,则继续向上层函数中找寻找,我们称这种链式的查询关系为作用域链。
我们来看一个具体的例子帮助大家理解:
<script>
var b = 10;
function f1(){
var a = 100;
function f2(){
console.log(a);
}
console.log(b);
f2();
}
f1();
</script>
递归调用
递归调用是函数嵌套中的一种特殊的调用,它指的是在一个函数内调用自身的过程。
递归函数在某些问题的解决中非常合适,但是其消耗的内存很大,因此在开发中尽量避免使用。
我们来看一个递归函数的经典例题:求斐波那契数列的第N项值
斐波那契数列指的是这样的数列:“1,1,2,3,5,8,13......”
他的特点是“这个数列从第三个数开始,每一项的值等于其前面两项的和”
<script>
function Fibonacci(n){
if(n<0){
console.log("输入有误,n不能小于0!");
}
else if(n==0){
return 0;
}
else if(n==1){
return 1;
}
else if(n>1){
return Fibonacci(n-1) + Fibonacci(n-2);
}
}
console.log(Fibonacci(10));
</script>
闭包函数
我们可以在内嵌函数中访问外部的变量,但我们却不能在内嵌函数外访问内嵌函数的变量,但有时我们又需要使用内嵌函数内的变量。这时我们就可以使用闭包函数。 闭包函数有两个特点:
- 闭包函数可以在函数外部读取函数内部的变量。
- 闭包函数可以让变量始终保存在内存中。
那么闭包函数如何实现呢?
闭包常见的创建方式就是在一个函数内部创建另一个函数,通过另一个函数来访问这个函数内部的局部变量。
来看一个例子:
<script>
function f1(){
var times = 0;
//c保存函数的返回值
var c = function(){
return ++times;
}
return c;
}
//count保存f1()的返回值
var count = f1();
console.log(count());
console.log(count());
console.log(count());
console.log(count());
console.log(count());
</script>
闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。
直观的说就是形成一个不销毁的栈环境。