闭包
首先说说闭包,闭包的官方定义:能够访问其他函数作用域的变量的函数,并且该函数可以起到让其他作用域中变量保存的作用。最常见的用法就是在父函数中
套用子函数来用闭包。为什么要用闭包呢,任何一个技术出现的前提必然是需求。要知道js中是没有静态变量的,函数变量在函数执行后立即被垃圾回收,我们当然可以用全局变量,但是过多的全局变量会导致代码难以维护,所以我们就要采用闭包。代码示例如下,在函数A执行后,匿名函数被外界引用,那么函数A中的变量i就没有随着函数A的执行完毕被垃圾回收,此变量一直保持在内存中。
function A(){
var i=1;
return function(){
alert(++i);
}
}
var b=A();
b();//2
b();//3
闭包的第二种用法,就是循环绑定事件了,循环绑定如下事件后,单击每个div,触发的都是alert(9),因为代码是在单击时执行的,所以会去查找循环后的i变量i=10;
for (var i=0;i<10;i++){
div.bind('click',function(){
alert(i);
})
}
修改如下,讲变量i复制一份给index,则内部的匿名函数就形成了闭包,他可以让传递进来的index实参保存,不被垃圾回收。
for(var i=0;i<10;i++){
div.bind('click',(function(index){
return function(){
alert(index)
}
})(i))
}
作用域与作用域链
在此需要说一下执行环境的概念,作用域是语言中通用的概念,而作用域链与执行环境是js中特有的。执行一个函数时,都会进入一个执行环境,这个执行环境中存储了当前
作用域的方法和属性。当前执行环境在执行栈的最底层,window的执行环境在最上层。访问一个变量,如果在当前执行环境中不存在,则需要沿着作用域链向上层执行环境中
去查找。当前代码执行完毕,当前执行环境销毁,将执行权返还给上层的执行环境。