2021-03-04闭包

闭包

作用域

  1. 函数内部可以使用全局变量。
  2. 函数外部不可以使用局部变量
  3. 当函数执行完毕,本作用域内的局部变量会被销毁。

函数分为两个阶段

  1. 定义阶段

    会在堆内存中开辟一个新的空间,将函数中的代码作为字符串存储进去。并将这个新空间的地址返回给一个变量。

  2. 调用阶段

    在执行空间中开辟一个新的空间,执行函数中的代码,声明新的变量,执行完代码后,该空间会被销毁,变量也会被销毁。

什么是闭包

有权访问另外一个函数作用域中的变量的函数。

闭包的特点:

  1. 函数嵌套函数
  2. 内部函数引用外部函数的变量。
    <script>
        var n = 10;
        var show = function() {
                var n2 = 20;
                function son() {
                    var n3 = 30;
                    console.log(n2);
                }
                return son;
            };
        var fn = show();
        console.log(fn);
        // ƒ son() {
        //             var n3 = 30;
        //             console.log(n2);
        //         }
    </script>

闭包的作用

内存管理机制:

​ 当有变量指向了一块内存地址时,因为随时可能会被调用,所以这块内存不会被销毁。

  1. 可以读取函数内部的变量

  2. 可以让这些变量的值始终保存在内存中。

  3. 将变量或者对象进行私有化。

            function person(name){
                var name = name;
                function sayName(){
                    console.log(name);
                }
                return sayName;
            }
            var fun = person("小明");
            fun(); //小明
    

循环注册点击事件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        button {
            font-size: 18px;
        }
    </style>
    <script>
        window.onload = function() {
            var btns = document.querySelectorAll("button");
            for (var i = 0; i < btns.length; i++) {
                btns[i].onclick = btnClick(i);

                //    相当于下面的代码。
                // btns[i].onclick = function() {
                //     alert(i);//结果5
                // }

                // btns[0] => alert(0)
                // btns[1] => alert(1)
            }

            function btnClick(i) {
                return function() {
                    alert(i);
                }
            }
        }
    </script>
</head>

<body>
    <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>
</body>

</html>

return和闭包区别

闭包可以保护里面的东西

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        function show() {
            var obj = {
                name: "提莫",
                price: 6300
            }
            return obj;
        }
        var tm = show();
        tm.price = 0;
        // console.log(tm);
        //Object
        // name: "提莫"
        // price: 0
        // __proto__: Object

        function show2() {
            var obj = {
                name: "提莫",
                price: 6300
            }

            function getPrice() {
                return obj.price;
            }

            function setPrice(price) {
                if (price < 4800) {
                    alert("该价格不可更改!")
                } else {
                    obj.price = price;
                    alert(price)
                }
            }
            return {
                getPrice: getPrice,
                setPrice: setPrice
            }
        }
        var tm2 = show2();
        tm2.setPrice(4801); //4801
        console.log(tm2.getPrice);
        //ƒ getPrice() {
        // return obj.price;
        // }
    </script>
</body>

</html>

闭包的缺点

容易造成内存泄露。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 100px;
            height: 100px;
            background-color: brown;
            font-size: 22px;
            line-height: 100px;
            text-align: center;
            margin: 100px;
        }
    </style>
    <script>
        window.onload = function() {
            let divs = document.querySelectorAll("div");
            divs.forEach(function(item) {
                item.addEventListener("click", function() {
                    console.log(this.innerHTML);
                    // console.log(item.innerHTML);不用item,使用item会形成闭包
                    // console.log(this);
                })
            })
        }
    </script>
</head>

<body>
    <div>云梦山</div>
    <div>凤凰山</div>
</body>

</html>

闭包中的this

this对象是在运行时基于函数的执行环境绑定的,谁调用this就是谁。如果在全局范围中,this就是window,如果在对象内部,this就指向这个对象。
因为闭包并不属于这个对象的属性或方法。所以在闭包中的this是指向window的

<script>
       let tm = {
            user: "提莫",
            get: function() {
                let _this = this; //改变this指向
                return function() {
                    console.log(_this);
                    return _this.user;
                }
            }
        }
        let a = tm.get();
        console.log(a());//window
        //{user: "提莫", get: ƒ} 
        // 提莫
</script>
<script>
        let tm = {
            user: "提莫",
            get: function() {
                return () => {
                    return this.user;
                }
            }
        }
        let a = tm.get();
        console.log(a()); //提莫
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值