轻松掌握js闭包

前言

对于 JavaScript 程序员来讲,闭包(closure)是一个难懂又必需要知道的东西。其实闭包很easy,只是太过理论术语,感受好像很复杂而已。下面就带着轻松的心态,来战胜闭包吧。node

什么是闭包?

简单一句话,当一个函数里面嵌套了一个函数的,而且内部函数用到了外部函数里的变量时,这个总体就造成了一个闭包结构。但主要是这个结构有啥特色?有啥用?程序员

闭包的特色?

看一个例子:bash

var func = function(){ 
    var a = 1; 
     return function(){ 
        a++; 
        console.log ( a ); 
    }
};
var f = func(); 
f(); // 输出:2 
f(); // 输出:3 
复制代码
解析:
  • 在上例中,func函数里面返回了一个函数,也能够说嵌套了一个子函数,内部函数里用到了外部函数的变量a.此时造成了闭包结构。
  • 调用流程:首先f = func(),此时func()函数被调用,咱们都知道函数的局部变量会随着函数调用的结束而被销毁。可是f()调用以后发现依然能够访a变量,说明局部变量a并无被销毁。这就是闭包的一个特性:父函数的局部变量若是在子函数中有用到,那么这个局部变量就不会被销毁。就是子函数在对父函数的呼唤,你别销毁这个变量,我还要用呢。

OK,那么了解了闭包的特性,就得知道有啥用吧,否则学了就没啥意思了,接着往下看。闭包

闭包的做用?

建立私有做用域

使用场景1:实现一个业务,有多个函数。函数

粗暴的写法:ui

var _count = 1;
    var m1 = function(){
        var b = _count + 1
    };
    
    var m2 = function(){
    };
复制代码

这种写法,就是什么东西都暴露在全局下了,变量_count也会很容易被篡改。好的写法,应该是,能让外界访问的就暴露给外界,不须要的外界就访问不了。spa

此时咱们就能够采用闭包:以下code

var module = (function(){
    var _count = 0;
    var m1 = function(){
    };
    
    var m2 = function(){
    };
    return {
        m1 : m1,
        m2 : m2
    };
})();

module.m1();

这样 外界就访问不到module的局部变量了,对应的操做暴露出来,又能够访问。
复制代码

使用场景2:点击对应节点,弹出对应的位置索引。索引

若是不经思考的话,你可能写出以下的代码,但实际上这样写,无论点哪一个都会弹出2
var nodes = document.getElementsByTagName( 'div' ); 
for ( var i = 0, i < 2; i++ ){ 
     nodes[ i ].onclick = function(){ 
        alert ( i ); 
     } 
}; 
复制代码

解析: 首先,执行循环,每次循环都声明一个点击是事件,以下:事件

第一次循环
 nodes[0].onclick = function(){ 
    alert ( i ); 
} 
第二次循环
 nodes[1].onclick = function(){ 
    alert ( i ); 
} 

复制代码

解析:首先,咱们要知道在js语言中,for循环不是一个代码块,也就是说没有造成一个单独的做用域,i在全局做用域均可以被访问,因此,执行完循环后,i的值已经变成5.而事件只有在点击的时候才执行内部的代码,当咱们点击的时候,此时弹出的i已是循环事后的i了,就是5了。

那怎么样才能实现咱们要的效果呢?既然想弹出对应的i,咱们在每次循环的时候,是否是就应该传入一个惟一的i,也就是每一个i都有本身的做用域,不会被覆盖。 想到做用域,那天然是想到函数了,因此咱们就在点击事件外,包裹一个函数,把每次循环的i当作参数传入进去, 此时参数是局部变量,以下:

var nodes = document.getElementsByTagName( 'div' ); 
for ( var i = 0, i < 2; i++ ){ 
    (function(j){
        nodes[ j ].onclick = function(){ 
            alert ( j ); 
        } 
    })(i)
     
}; 
复制代码

解析: 其实此时,是否是造成了一个闭包结构了,当即执行函数内包裹了点击事件函数,且点击事件函数,用到了外层函数的变量j。因此这个j是不会被销毁的,因此在点击的时候,咱们天然就能访问到对应函数的这个参数j了.

固然,也有不少种方法能够实现这个需求,由于今天讲的是闭包,就不说别的了。

总结

闭包的造成条件

  • 函数嵌套函数
  • 内部的函数引用了外部函数的参数和变量

闭包的特色

  • 外部函数中,被内部函数引用的参数和变量不会被销毁

若有错误,欢迎你们纠正

相关文章
相关标签/搜索