MarginLon MarginLon
首页
  • Web

    • Web基础
    • Web布局
    • CodeSnippet
  • Vue

    • Vue
  • React

    • React
  • Node.js

    • Node.js
  • 技术文档
  • UI组件库
  • 动画库
  • 图形库
  • 桌面端
  • 学习笔记
  • 生活笔记
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

MarginLon

http://info.cern.ch
首页
  • Web

    • Web基础
    • Web布局
    • CodeSnippet
  • Vue

    • Vue
  • React

    • React
  • Node.js

    • Node.js
  • 技术文档
  • UI组件库
  • 动画库
  • 图形库
  • 桌面端
  • 学习笔记
  • 生活笔记
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 数据类型 类型检测 类型转换
  • 精度问题
  • 堆栈内存 函数底层运行机制 块级作用域
  • GC机制 闭包作用域 let/const/var
  • 闭包应用
    • 1. 闭包应用:循环中的闭包处理方案
    • 1.1. 循环事件绑定
    • 1.2. 循环定时器
  • DOM
  • BOM
  • This指向
  • 浏览器渲染机制 CRP优化 事件循环机制
  • 函数防抖节流
  • 模块化 柯里化
  • 构造函数 原型
  • CLASS
  • 工厂设计模式 深浅拷贝 深浅合并
  • Iterator/Generator
  • Promise/ Async/ Await
  • HTTP/跨域
  • API
  • AJAX
  • 事件
  • 《JavaScript高级程序设计(第4版)》
MarginLon
2022-04-12
目录

闭包应用

  • 1. 闭包应用:循环中的闭包处理方案
  • 1.1. 循环事件绑定
  • 1.2. 循环定时器

# 1. 闭包应用:循环中的闭包处理方案


# 1.1. 循环事件绑定

  var buttons = document.querySelectorAll('button');
  for (var i = 0; i < buttons.length; i++) {
    // i=0 buttons[0] 第一个按钮
    // i=1 buttons[1] 第二个按钮
    // ....
    // 每一轮循环 i 变量的值 和 需要获取对应某个按钮的索引是一样的  buttons[i]
    buttons[i].onclick = function(){
       console.log('获取当前按钮索引:${i}');
       //不能实现
    };
  }

  //方案1.1:基于“闭包”
  // [每一轮循环都产生一个闭包,存储对应索引;
  // 点击事件触发,执行对应函数,让其上级context闭包]
  var buttons = document.querySelectorAll('button');
  for (var i = 0; i < buttons.length; i++) {
      // 每一轮循环形成一个闭包,存储私有变量i的值
      //    + 自执行函数执行,产生EC(A) 私有形参i=0/1/2
      //    + EC(A)中有个小函数,让全局buttons中的某一项占用创建的函数
    (function(i) {
       buttons[i].onclick = function(){
        console.log('获取当前按钮索引:${i}');
       };
    })(i);
  }

  //方案1.2:
  var buttons = document.querySelectorAll('button');
  for (var i = 0; i < buttons.length; i++) {
       buttons[i].onclick = (function(i){
        return function () {
            console.log('获取当前按钮索引:${i}');
            };
    })(i);
  }
  //方案1.2注解
  var obj = { //返回值赋值给fn
      fn: (function(){
          console.log('大函数');
          return function(){
              console.log('小函数');
          }
      })()
  };
  obj.fn();//执行返回的小函数

  //方案1.3 基于let也是闭包
  let buttons = document.querySelectorAll('button');
  for (let i = 0; i < buttons.length; i++) i{
       buttons[i].onclick = function(){
            console.log('获取当前按钮索引:${i}');
            };
  }

  //方案1.4 Nodelist forEach
  var buttons = document.querySelectorAll('button');
  buttons.forEach(function(item,index){
    item.onclick = function(){
      console.log('获取当前按钮索引:${i}');
    };
  });

  //方案2 自定义属性
  var buttons = document.querySelectorAll('button');
  for (var i = 0; i < buttons.length; i++) i{
      // 每一轮循环给当前button设置自定义属性存索引
       buttons[i].myIndex = i;
       buttons[i].onclick = function(){
           // this -> 当前点击的按钮
            console.log('获取当前按钮索引:${this.myIndex}');
       };
  }

  //方案3 事件委托 html <button index='i'></button>;
  // 无论点击body中的谁,都会触发body的点击事件
  // ev.target事件源:具体点击的是谁
  document.body.onclick = function(ev) {
      var target = ev.target
          targetTag = target.tagName;
      if(targetTag==="BUTTON"){
          var index = target.getAttribute('index');
          console.log('获取当前按钮索引:${index}');
      }
  };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

# 1.2. 循环定时器

// 实现每间隔1秒输出 0 1 2
for (var i = 0; i < 3; i++) {
    setTimeout(function () {
        console.log(i);
    }, i * 1000);
}

// 1.
for (let i = 0; i < 3; i++) {
    setTimeout(function () {
        console.log(i);
    }, i * 1000);
}

//2.
let i = 0
for (; i < 3; i++) {
    (function(i){
      setTimeout(function () {
        console.log(i);
    }, i * 1000);
    })(i);
}

//3.
const fn = i => {
  return function () {
        console.log(i);
    };
};
let i = 0;
for (; i < 3; i++) {
      setTimeout(fn(i), i * 1000);
}

//4. 
let i = 0;
for (; i < 3; i++) {
      setTimeout(function (n) {
        console.log(n);
    }, i * 1000,i);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

编辑 (opens new window)
上次更新: 2023/04/01, 15:26:22
GC机制 闭包作用域 let/const/var
DOM

← GC机制 闭包作用域 let/const/var DOM→

最近更新
01
KnockoutJS
11-12
02
综述
10-17
03
前言
10-12
更多文章>
Theme by Vdoing | Copyright © 2019-2024 MarginLon | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式