JavaScript学习总结2--作用域和闭包
闭包是JavaScript中最难理解的知识点之一.
在理解闭包之前,首先要清楚JavaScript中的作用域只有2种,全局作用域和局部作用域(函数内部).
全局作用域很好理解,而局部作用域就表示一个函数(或方法)function形成的一个独立的作用域
例如:
var a=0; //这是全局作用域中的变量 function fnA(){ var b=1; console.log(a); //局部作用域可访问全局作用域下的变量a function fnAa(){ var c=2; console.log(a); //嵌套了一层函数后,内部的函数fnAa依然可以访问全局作用域下的变量a } console.log(c); //离开fnAa作用域,外部函数就无法访问内部的变量c了(这里会报错) } fnA(); console.log(b); //同样的,在全局作用域下也无法访问fnA内部的变量b
下面开始重点理解一下闭包.
假设页面中有10个li元素,需要为每一个li绑定一个click事件,想当然的我们会这样写
//省略之前代码 var oLi=document.getElementsByTagName("li"); //使用for循环 for(var i=0;i<oLi.length;i++){ oLi[i].onclick=function(){ alert("我是第"+i+"个li元素"); } }
乍一看这样写似乎没问题,但是实际上这段代码运行后点击每一个li元素都会弹出我是第10个li元素
为什么呢?
上面这段代码中,oLi[i].onclick实际上只调用到了for循环运行完之后的i,简单来说i的值并没有在每一次执行for循环时都被onclick事件处理的匿名函数调用
触发click事件时,匿名函数先在自己内部寻找变量i,没有找到则继续向上在父级作用域中寻找,而此时for循环执行完毕,i的值为10,所以每次调用都只拿到了10
函数调用外部变量的时候就构成了一个闭包,所以我们要做的就是构建一个只有自己本身才能访问的闭包,保存只给自己使用的变量
简单粗暴直接上代码
var oLi=document.getElementsByTagName('li'); for(var i=0;i<oLi.length;i++){ (function(i){ oLi[i].onclick=function(){ console.log("我是第"+i+"个元素"); } })(i); };