(自用面试题)闭包是什么?

84 阅读1分钟

闭包的定义

闭包(closure)指的是引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的,它是作用域的一种特殊应用。

触发闭包的情况

  • 函数当作参数被传递。

  • 函数当作返回值被返回。

  • 立即调用的函数表达式。

eg:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>    
</body>

<script>
    // 函数当作参数被传递
    function fn(cb) {
        const a = 100;
        cb();
    }
    const a = 500;
    fn(function () {
        console.log(a);// 500
    });

    // 函数当作返回值被返回
    function fn() {
        const a = 1;
        return function () {
            console.log(a);// 1
        };
    }
    const a = 5;
    const cb = fn();
    cb();

    // 立即调用的函数表达式
    (function (index) {
        console.log(index);// 10
    })(10);
</script>
</html>

闭包的应用

  1. 隐藏变量。
    eg:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>    
</body>

<script>
    // 隐藏了data这个变量,它只能在fn中使用
    function fn() {
        const data = {};
        return {
            set: function (key, val) {
                data[key] = val;
            },
            get: function (val) {
                return data[val];
            }
        };
    }
    const json = fn();
    json.set("age", 18);
    console.log(json.get("age"));
</script>
</html>
  1. 解决用来计数的循环变量泄露为全局变量的问题。
    eg:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button>0</button>
    <button>1</button>
    <button>2</button>
    <button>3</button>
    <button>4</button>
</body>

<script>
    const aBtns = document.getElementsByTagName("button");

    for (var i = 0; i < aBtns.length; i++) {
        // aBtns[i].onclick = function () {
        //     console.log(i);
        // }
        (function (index) {
            aBtns[i].onclick = function () {
            console.log(index);
            }      
        })(i);
    }
</script>
</html>

拓展:
自由变量:不在自己作用域内的变量就是自由变量。
想知道自由变量的值是多少要去函数定义的外层作用域中去查找,与函数调用的位置无关,只与函数定义的位置有关。
eg:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
</body>

<script>
    const a = 100;

    function fn() {
        console.log(a); // 自由变量
    }
</script>
</html>