前端面试之JavaScript中的闭包!

前端面试之JavaScript中的闭包!

闭包

闭包( closure )指有权访问另一个函数作用域中变量的函数。 ----- JavaScript 高级程序设计

闭包其实可以理解为是一个函数

简单理解就是,一个作用域可以访问另外一个函数内部的局部变量。

 <script>
    //   闭包(closure)指有权访问另一个函数作用域中变量的函数。
    function fn() {
        var num = 29;
        function fn2() {
            console.log(num); // 29
        }
        fn2();
    }
    debugger
    fn();
    </script>

闭包就是当前作用域可以访问另一个函数的作用域中的局部变量!另一个函数就叫做闭包函数!也就是说产生了闭包!

被访问的这个变量的这个函数就叫做闭包函数!

闭包的作用!

闭包的作用:延伸了变量的作用范围!

 //   闭包(closure)指有权访问另一个函数作用域中变量的函数。
        // 一个作用域可以访问另外一个函数的局部变量
        // 我们fn外面的作用域可以访问fn内部的局部变量
       
        function fn() {
            var num = 29;

            // function fn2() {
            //     console.log(num); // 29
            // }
            // return fn2; // 把fn2这个函数返回回去!

            // 简化
            return function () {
                console.log(num); // 29
            }
        }
        var f = fn(); // f接收的就是一个函数, 那么我们调用他不就可以实现外面的作用域可以访问fn内部的局部变量了嘛!
        f(); // 29

闭包的案例

点击li输出当前li的索引号

 // 闭包应用-点击1i输出当前1i的索引号
        // 闭包应用-点击1i输出当前1i的索引号
// 我们可以利用动态添加属性的方式

        var lis = document.querySelector('.nav').querySelectorAll('li');
        // for (var i = 0; i < lis.length; i++) {
        //     lis[i].index = i;
        //     lis[i].onclick = function () {
        //         console.log(this.index)
        //     }
        // }

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

闭包应用-3秒钟之后,打印所有1i元素的内容

 // 闭包应用-3秒钟之后,打印所有1i元素的内容
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            (function(i) {
                setTimeout(function() {
                console.log(lis[i].innerHTML)
            }, 2000)
            })(i);
          
        }

计算打车价格

  //闭包应用-计算打车价格

        // 打车起步价13(3公里内),  之后每多一公里增加 5块钱.  用户输入公里数就可以计算打车价格
        // 如果有拥堵情况,总价格多收取10块钱拥堵费
        // function fn() {};
        // fn();
        var car = (function () {
            var start = 13; // 起步价  局部变量
            var total = 0; // 总价  局部变量
            return {
                // 正常的总价
                price: function (n) {
                    if (n <= 3) {
                        total = start;
                    } else {
                        total = start + (n - 3) * 5
                    }
                    return total;
                },
                // 拥堵之后的费用
                yd: function (flag) {
                    return flag ? total + 10 : total;
                }
            }
        })();
        console.log(car.price(5)); // 23
        console.log(car.yd(true)); // 33

        console.log(car.price(1)); // 13
        console.log(car.yd(false)); // 13

关于闭包的思考题!
下面的函数中有没有产生闭包呢?

        var names = 'The Window';
        var obj = {
            names: 'My obj',
            getNameFunc: function() {
                return function() {
                    return this.names;
                }
            }
        }
        console.log(obj.getNameFunc()()); // The Window
        // Why
    var names = 'The Window';
        var obj = {
            names: 'My obj',
            getNameFunc: function() {
                var that = this;
                return function() {
                    return that.names;
                }
            }
        }
        console.log(obj.getNameFunc()()); 
posted @ 2020-12-15 15:11  lvhanghmm  阅读(110)  评论(0)    收藏  举报