前端学习笔记:JavaScript闭包

黑马Pink老师的javaScript进阶面向对象ES6教程:
https://www.bilibili.com/video/BV1Kt411w7MP?p=63

本文在原教程的基础上对目录结构进行了排序和裁剪。针对视频中的讲解、案例、PPT和源码材料作了一些总结,仅用于个人复习以及学习交流分享。

1. 变量作用域

变量根据作用域的不同分为两种:全局变量和局部变量。

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

2. 闭包的定义

闭包(closure)指有权访问另一个函数作用域中变量的函数。

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

<script>
 function fn1(){
    
        // fn1 就是闭包函数
    var num = 10;
    function fn2(){
    
    
      console.log(num); // 10
    }
       fn2()
 }
  fn1();
</script>

3. 闭包的作用

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

4. 闭包案例

4.1 循环注册点击事件

    <ul class="nav">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <script>
        // 1. 动态添加属性
        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. 利用闭包
        for (var i = 0; i < lis.length; i++) {
      
      
            // 利用for循环创建了4个立即执行函数
            // 立即执行函数也成为小闭包,因为立即执行函数里面的任何一个函数都可以使用它的i变量
            (function (i) {
      
      
                lis[i].onclick = function () {
      
      
                    console.log(i);
                }
            })(i);
        }
    </script>

4.2 循环中的setTimeout()

    <ul class="nav">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <script>
        // 3秒钟之后,打印所有li的内容
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
      
      
            (function (i) {
      
      
                setTimeout(function () {
      
      
                    console.log(lis[i].innerHTML);
                }, 3000);
            })(i);
        }
    </script>

4.3 计算打车价格

// 打车起步价13(3公里内),之后每多一公里增加5块钱,用户输入公里数可以计算打车价格
// 如果有拥堵情况,总价格多收取10块钱拥堵费
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;
        },
        // 拥堵之后的价格
        yongdu: function (flag) {
    
    
            return flag ? total + 10 : total;
        }
    }
})();
console.log(car.price(5));
console.log(car.yongdu(true));

4.4 面试题

// 思考题1:
var name = "The window";
var object = {
    
    
    name: "My object",
    getNameFunc: function () {
    
    
        return function () {
    
    
            return this.name;
        }
    }
};
console.log(object.getNameFunc()()); // The window

// 思考题2:
var name = "The window";
var object = {
    
    
    name: "My object",
    getNameFunc: function () {
    
    
        var that = this;  // this指向了object
        return function () {
    
    
            return that.name;
        }
    }
};
console.log(object.getNameFunc()()); // My object

おすすめ

転載: blog.csdn.net/ycsss/article/details/121022872