针对前端必会的闭包,梳理一番,妈妈不再用担忧个人闭包了~~~~

闭包

1.1 什么是闭包

  • 闭包(closure): 指有权访问另外一个函数做用域中变量的函数。
  • 通俗讲:一个做用域能够访问另一个函数内部的局部变量。

1.2 观察下面代码的结果

for(var i = 0; i < 10; i++) {  
    setTimeout(function() {  
        console.log(i);
    }, 1000);  
}
//输出结果都为10,由于for()循环过程当中每次传值,匿名函数并无执行,至关于执行10次function(){console.log(i);},循环结束i变为10,因此输出所有为10;
复制代码
for(var i = 0; i < 10; i++) {  
    (function(i) {  
        setTimeout(function() {  
            console.log(i);
        }, 1000);  
    })(i);  
}
//外部匿名函数当即执行,把 i 做为参数,赋值给内部的 i ,由于是当即执行,因此每次循环输出不一样值。
复制代码

1.3 变量的做用域与同步异步复习

变量根据做用域的不一样分为两种:全局变量和局部变量

  • 函数内部可使用全局变量。
  • 函数外部不可使用局部变量。
  • 当函数执行完毕,本做用域内的局部变量会销毁。

同步异步

  • 同步:因为js单线程,同步任务都在主线程上排队执行,前面任务没执行完成,后面的任务会一直等待;闭包

  • 异步:不进入主线程,进入任务队列,等待主线程任务执行完成后开始执行。好比咱们学的异步操做setTimeout和setInterval,等待主线程任务执行完,在开始执行里面的函数异步

1.3闭包的做用

  • 特性:可实现函数外访问函数内变量,外层变量能够不被垃圾回收机制回收,即延伸变量的做用范围函数

  • 缺点: 引用外层变量不被回收,会相比其余函数占用更高内存,使用不当容易形成内存泄漏。ui

1.4 经典案例

利用闭包的方式获得当前li 的索引号

for (var i = 0; i < lis.length; i++) {
// 利用for循环建立了当即执行函数
// 当即执行函数也成为小闭包由于当即执行函数里面的任何一个函数均可以使用它的i这变量
(function(i) {
    lis[i].onclick = function() {
      console.log(i);
    }
 })(i);
}
复制代码

方法二: 使用自定义属性,给每一个对象添加一个索引属性

for (var i = 0; i < lis.length; i++) {
function(i) {
    lis[i].index = i;
    lis[i].onclick = function() {
      console.log(this.index);
    }
 }
}
复制代码

方法三: 利用ES6 的 Let 声明变量就能够更好的解决上述问题

for (let i = 0; i < lis.length; i++) {
function(i) {
    lis[i].onclick = function() {
      console.log(i)
    }
 }
}
复制代码
相关文章
相关标签/搜索