利用闭包解决无法获取对应索引的问题

闭包: 

  闭包就是一个函数可以访问另外一个函数内部的变量。函数内部的变量很明显是一个局部变量。

  在JS中,我们所定义的任意一个函数,都可以看作是闭包。只不过最明显的存在与嵌套关系的函数中,内部的子函数 可以 访问父函数 中的变量。

  但是,我们想要从父函数的外部访问其内部的局部变量,该怎么实现?

  通过观察,发现子函数可以访问父函数的局部变量,所以我们尝试着让这个内部的子函数作为桥梁连通内外,让外部有能力去访问一个函数内部的变量。

  for(var i = 0; i < 10; i++){
        //一个函数就是一个闭包
        (function(j){
            setTimeout(function () {
                console.log("i:",j);
            },1000);
        })(i);
    }

上面的代码 :内层定时器函数引用外层IIFE传的值形成闭包。

      setTimout作外层函数,setTimeout的第一个回调函数作内层函数,内层引用外层的参数形成闭包。

 

例如:点击页面li中的内容,弹出 "您点击了第 N 条内容" 

 

写在最前面: 这里声明的变量都是使用var, 如果使用es6新增的let关键字 则可以正常访问。

      因为var是用来定义函数级作用域变量的,并且不能存储数据;

      let关键字是定义块级作用域变量的,可以存储数据。

例如:

let lis = document.querySelectorAll('li');
        for(let i = 0; i < lis.length; i++) {
            lis[i].onclick = function() {
                alert('您点击了第' + Number(i + 1) + '条内容')
            }
        }

 

以下三种方法讨论使用var声明如何解决:

 

第一种方法:

  利用this,对应索引的方法

  

 for(var i = 0; i < lis.length; i++) {
        lis[i].index = i;
        lis[i].onclick = function() {
            console.log(this.index)
            alert('您点击了第' + Number(this.index + 1) + '条内容')
        }
    }

第二种方法:

  利用闭包

for(var i = 0; i < lis.length; i++) {
        (function(j) {
            lis[j].onclick = function() {
                alert('您点击了第' + Number(j + 1) + '条内容')
            }
        })(i)
    }

 第三种方法:

  利用事件委托

    事件委托

      借助事件冒泡的原理,用父元素去处理子元素中具有相同的事件。这样可以减少DOM的操作。
    事件委托优点:           
      1.减少事件数量;2.避免内存外泄;3.预言未来元素
   // list为ul标签的id
    let list = document.getElementById('list');
    for(var i = 0; i < lis.length; i++) {
        // 为每一个li标签添加自定义属性
        lis[i].setAttribute('data-index', i)
    }
    list.onclick = function(e) {
        var t = e.target || e.srcElement;
        alert('您点击了第' + (Number(t.getAttribute('data-index'))+1) + '条内容')
    }

 

 
posted @ 2021-04-13 21:13  没有茅台喝啤酒也行  阅读(74)  评论(0编辑  收藏  举报