闭包,立即执行一次讲清

233 阅读2分钟

闭包

我对闭包的理解是,依靠内层的函数的变量能够访问外层函数的作用域这一特效,将之有效结合并且使用的方式叫做闭包。如以下代码:

function a(){
    var num = 1;
    function b(){
        console.log(num)
    }
    b()
}
a()

此时b中本身并没有num,于是它从外面找到了a的变量并进行了使用,这种情况就叫做闭包。 闭包有什么作用呢?闭包本身只是一种情况的概念,实际开发中它主要有两个作用:1.使得函数变量的值永远的存在内存中2.使得外部函数可以读取到函数内部的变量值。如以下代码:

function a(){
    const num = 1;
    function a1(){
        console.log(num)
    }
    return a1;
}
const b = a();
b()  //1

此时,因为在a函数的外部使用了b函数,使得a函数内部的变量能够在外部被调用,从而使得变量num并没有随着函数的执行完毕被销毁,始终会保存在变量中。总结来看,第一,外层函数嵌套内层函数; 第二, 内层函数使用外层函数的局部变量; 第三,把内层函数作为外层函数的返回值!这样就形成了一个闭包 给出阮一峰文章的两道题目的答案并给出我的分析

1.var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      return function(){
        return this.name;
      };

    }

  };

  alert(object.getNameFunc()());
  此时分析,第一个函数执行完毕的时候,返回的值是一个函数所以也就是要我们输出alert(function(){return this.name}),所以调用它的的是window,返回the Window
2.var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };

    }

  };

  alert(object.getNameFunc()());
  注意此时将this的值赋给了that,于是this会去找本身的name值,找不到就往外部的函数找,找到了object的name,于是输出My Object

立即执行

刚刚的闭包使用了内部变量访问外部变量的特性,但是很多时候我们不想要这个特性,于是有了立即执行函数。直接给出代码

(function(){
    fn()
})()

此时函数内部的变量无法再访问外部的变量,外部的变量也无法再访问内部的函数。立即执行函数的作用就在于创建了一片独立的作用域,在没有块级作用域的时代常常用来包装var形成的for循环造成的bug,用立即执行函数解决问题

var liList = ul.getElementsByTagName('li')
for(var i=0; i<6; i++){
  !function(ii){
    liList[ii].onclick = function(){
      alert(ii) // 0、1、2、3、4、5       此时输出了我们想要的值
    }
  }(i)
}