成长(8/2000)——面试题合集5

2021-06-11  本文已影响0人  Kiki_Q

闭包的底层原理

闭包的底层原理其实就是作用域链被保存下来的原因,具体往下看

作用域链

要点:

var global;
function a() {
    function b() {
        var bb = 123;
        aa = 0;
    }
    var aa = 123;
    b();
}

a()  //第一个a函数
a() //第二个a函数
a定义

第一个a函数执行前会先定义,定义的时候会产生它的作用域链,因为是全局函数,所以会产生GO,可以看出只有global和a函数;

a执行

当a函数执行的时候会产生它自己的AO对象(函数作用域),如图,aa变量和b函数;

以上讲述了函数中作用域链的产生方式;注意当第二个a函数执行他会有他自己的作用域链,它们之间是互不影响的!

下面我们通过以下函数说明闭包的原理:

function a() {
    var aa = 123;
    function b() {
        var bb = 234;
        console.log(aa)
    }
    return b;
}

var res = a();
res();
Scope1.png Scope2.png Scope3.png

就看图1和2就可以,a执行和b定义的作用域链是一样的,a执行完会断开自己的作用域链,但是此时b定义的作用域链仍存在;闭包返回的是函数,此时还未执行,属于定义阶段,所以可以访问作用域链上的变量

闭包的运用

<!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 id="loginBtn">登录</button>
</body>
<script>
    
    let createLogin = function () {
        let div = document.createElement("div");
        div.innerHTML = "这是登录弹窗";
        div.style.display = "none";
        document.body.appendChild(div);
        return div;
    }

    let getSingle = function (fn) {
        var result;
        return function () {
            return result || ( result = fn.apply(this, arguments) )
        }
    }

    let create = getSingle(createLogin);

    document.getElementById("loginBtn").onclick = function () {
        let loginLay = create();
        loginLay.style.display = "block";
    }
</script>
</html>
上一篇 下一篇

猜你喜欢

热点阅读