JavaScript——浅谈嵌套与递归,闭包函数

192 阅读2分钟

这是我参与更文挑战的第12天,活动详情查看: 更文挑战

嵌套与递归

嵌套函数与作用域链

首先我们来看什么是嵌套函数。 嵌套函数就是在一个函数内部定义另一个函数。

知道了什么是嵌套函数,那什么是作用域链呢?

在内层函数执行过程中可能会用到外部函数的变量,这时内层函数首先会在当前函数内找这个变量,如果找不到则在外层函数中继续找该变量,如果让找不到,则继续向上层函数中找寻找,我们称这种链式的查询关系为作用域链。

我们来看一个具体的例子帮助大家理解:

<script>
      var b = 10;
      function f1(){
          var a = 100;
          function f2(){
            console.log(a);
          }
          console.log(b);
          f2();
      } 
      f1();
    </script>

image.png

递归调用

递归调用是函数嵌套中的一种特殊的调用,它指的是在一个函数内调用自身的过程。

递归函数在某些问题的解决中非常合适,但是其消耗的内存很大,因此在开发中尽量避免使用。

我们来看一个递归函数的经典例题:求斐波那契数列的第N项值

斐波那契数列指的是这样的数列:“1,12,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>

image.png

闭包函数

我们可以在内嵌函数中访问外部的变量,但我们却不能在内嵌函数外访问内嵌函数的变量,但有时我们又需要使用内嵌函数内的变量。这时我们就可以使用闭包函数。 闭包函数有两个特点:

  1. 闭包函数可以在函数外部读取函数内部的变量。
  2. 闭包函数可以让变量始终保存在内存中。

那么闭包函数如何实现呢?

闭包常见的创建方式就是在一个函数内部创建另一个函数,通过另一个函数来访问这个函数内部的局部变量。

来看一个例子:

<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>

image.png 闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。

直观的说就是形成一个不销毁的栈环境。