lulujianglab / blog

:bento:lulujiang blog
https://lulujianglab.com/
83 stars 4 forks source link

谈谈js闭包 #19

Open lulujianglab opened 6 years ago

lulujianglab commented 6 years ago

闭包问题一直是面试中提到频率最高的问题,那到底什么是闭包呢,百度一下,我们会看到各种层出不穷的答案

所以,闭包是什么呢?

闭包的定义

创建闭包的方式

创建闭包的常见方式,就是在一个函数内部创建另一个函数

方式有很多种,比如,可以是在函数内部 return 一个函数(如上),也可以是在函数定义一个内部变量函数,并在函数内部执行(如上),或者是定义一个全局变量函数,在全局执行

image

或者是在定义一个对象方法,在外部执行

image

闭包的作用

闭包很好地解决了变量过多的问题

我们先来看一个例子

<button>1</button>
<button>2</button>
<button>3</button>
var buttons = document.querySelectorAll('button')
for (var i = 0; i < buttons.length; i++) {
  !function(index){
    buttons[i].onclick = function() {
      alert(index + 1)
    }
  }(i)
}

通过立即执行函数形成的闭包很好的解决了button变量的问题,如果没有闭包,我们就需要写多个这样的button点击事件

而且,如果没有闭包,我们以这种方式来定义点击事件,会出现常见的问题

var buttons = document.querySelectorAll('button')
for (var i = 0; i < buttons.length; i++) {
  buttons[i].onclick = function() {
    console.log(i)
  }
}

这样,每个函数打印的i值其实都是3。因为每个函数的作用域链中都保存着全局的活动对象,所以它们引用的都是同一个变量i。当开始执行 onclick 事件时,变量i的值已经是3了,此时每个对象都引用着保存变量i的同一个变量对象,所以在每个函数内部i的值都是3