闭包

概念

闭包就是能够读取其他函数内部变量的函数。

闭包即是可以访问另一个作用域的变量的一个函数。

比如,父级函数里面的变量,子级函数可以调用,那么这个子级函数就调用了父级函数的变量,即是闭包。

如下代码

// 闭包(closure)指有权访问另一个函数作用域中变量的函数。
// 闭包: 我们fun 这个函数作用域 访问了另外一个函数 fn 里面的局部变量 num
function fn() {
    var num = 10;
    function fun() {
         console.log(num);
    }
    fun();
}
fn();
应用

闭包的作用就是延长局部变量的作用范围

作用: 1.可以读取函数内部的变量,2.让这些变量的值始终保持在内存中,不会在调用后被自动清除。

缺点: 闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,

在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

利用闭包,点击获取li的索引值
<body>
    <ul class="nav">
        <li>榴莲</li>
        <li>臭豆腐</li>
        <li>鲱鱼罐头</li>
        <li>大猪蹄子</li>
    </ul>
    <script>
        // 闭包应用-点击li输出当前li的索引号

        // 利用闭包的方式得到当前小li 的索引号
        for (var i = 0; i < lis.length; i++) {
            // 利用for循环创建了4个立即执行函数
            // 立即执行函数也成为小闭包因为立即执行函数里面的任何一个函数都可以使用它的i这变量
            (function(i) {
                // console.log(i);
                lis[i].onclick = function() {
                    console.log(i);

                }
            })(i);
        }
    </script>
</body>
利用闭包,用定时器打印索引值
<body>
    <ul class="nav">
        <li>榴莲</li>
        <li>臭豆腐</li>
        <li>鲱鱼罐头</li>
        <li>大猪蹄子</li>
    </ul>
    <script>
        // 闭包应用-3秒钟之后,打印所有li元素的内容
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            (function(i) {
                setTimeout(function() {
                    console.log(lis[i].innerHTML);
                }, 3000)
            })(i);
        }
    </script>
</body>

递归

概念

递归,就是在运行的过程中调用自己。

递归函数是在一个函数通过函数名字调用自身的函数(函数自调用)。

应用

简洁,在遍历算法中,递归的实现明显要比循环简单得多

缺点:

1.存在时间和空间的消耗,

2.调用栈可能会溢出.影响性能.

利用递归,求n的阶乘
//利用递归函数求1~n的阶乘 1 * 2 * 3 * 4 * ..n
 function fn(n) {
     if (n == 1) { //结束条件
       return 1;
     }
     return n * fn(n - 1);
 }
 console.log(fn(3));
利用递归求斐波那契数列
// 利用递归函数求斐波那契数列(兔子序列)  1、1、2、3、5、8、13、21...
// 用户输入一个数字 n 就可以求出 这个数字对应的兔子序列值
// 我们只需要知道用户输入的n 的前面两项(n-1 n-2)就可以计算出n 对应的序列值
function fb(n) {
  if (n === 1 || n === 2) {
        return 1;
  }
  return fb(n - 1) + fb(n - 2);
}
console.log(fb(3));

闭包+递归 的面试题

写一个函数plus(1)(2)(3)….();

功能: 所有的括号中的参数全部相加,()个数不确定,结束的标志是()中没有参数传入;

考点: 闭包的使用+递归的调用,保存sum值。

function plus(n)
{
    var sum = 0;    //使用局部变量不污染全局
    //这段初始化还是要的,不然不能记录第一个传进来的值
    if ( arguments[0] != undefined )
  {
     sum += n;
        return getPlus;   
  }
    function getPlus(n)
    {
        if ( arguments[0] != undefined )
      {
         sum += n;
            return getPlus;     //实现递归           
      }
        else
      {
        return sum;
      }
    }

}
var a = plus(1)(2)(3)(4)(5)(6)(7)(8)(9)();
console.log(a);  //45
console.log( sum );  //报错。。。。

a = null ; //当不在使用该闭包时,记得释放,等于null以后,sum值就会在内存中释放。

题目转自https://www.cnblogs.com/shixiaomiao/p/4808177.html