【JS基础】闭包

概念:闭包是指有权访问另一个函数作用域中的变量的函数。在JS中,只有函数内部的子函数才能读取局部变量,所以闭包可以简单理解成‘定义在一个函数内部的函数’。
例题
 1 function test() {
 2     var n = 4399;
 3     function add(){
 4         n++;
 5         console.log(n);
 6     }
 7     return {n:n,add:add}
 8 }
 9 var result = test();
10 var result2 = test();
11 result.add(); // 4400
12 result.add(); // 4401
13 console.log(result.n); // 4399
function test() {
    var n = { num: 4399 };
    function add(){
        n.num++;
        console.log(n);
    }
    return {n:n,add:add}
}
var result = test();
var result2 = test();
result.add(); // {num: 4400}
result.add(); // {num: 4401}
console.log(result.n); // {num: 4401}

tips:上面例题会涉及深浅拷贝的问题

接下来看看用let声明和var声明的输出会有什么不同

function fn() {
    let arr = []
    for (let i = 0; i < 5; i++) {
        arr[i] = function() {
        return i
        }
    }
    return arr
}

let list = fn()
list[0]() // 输出 0
function fn() {
    let arr = []
    for (var i = 0; i < 5; i++) {
        arr[i] = function() {
            return i
        }
    }
    return arr
}

let list = fn()
list[0]() // 输出 5

下面是匿名函数,听说有人会混淆,所以也放这里供参考

var foo = {n:1};
(function(foo){
    console.log(foo.n); // 1
    foo.n = 3;
    var foo = {n:2};
    console.log(foo.n); // 2
})(foo);
console.log(foo.n); // 3

之前看到一个博主写的例子,这里展示给大家看看

var num = new Array();
for(var i=0; i<4; i++){
    num[i] = f1(i);
}
function f1(n){
     function f2(){
         console.log(n);
     }
     return f2;
}
num[2](); // 2
num[1](); // 1
num[0](); // 0
num[3](); // 3

有评论说不解为什么答案是这样,这里我说说自己的看法:

  f1使用了i做参数,把值拷贝给了n,而不是直接使用i变量,因此每个num[i]中的n都是不一样的,如果函数改成下面这样:

var num = new Array();
for(var i=0; i<4; i++){
  function f1(){
     function f2(){
         console.log(i);
     }
     return f2;
  }
    num[i] = f1();
}

num[2](); // 4
num[1](); // 4
num[0](); // 4
num[3](); // 4

  这里f1直接使用变量i,导致i没有被回收,所以每个num[i]中的i都是一样的。

总结:

  闭包使得Javascript的垃圾回收机制不会收回fn所占用的资源,因为a的内部函数b的执行需要依赖fn中的变量。

  看完文章,如果你还是不会解闭包的题目,那一定是我水平有限,说得不够明白,可以留言,我们一起探讨。

posted on 2022-11-13 20:53  WhoLovesAbby  阅读(47)  评论(0编辑  收藏  举报