我对js中的闭包的理解

来源:互联网 发布:mac sublime anaconda 编辑:程序博客网 时间:2024/04/19 19:16

闭包在JS是一个较为难以理解的东西,通过学习JS,我分享一下我的理解。
首先 我们先了解一下对于理解闭包概念的重要的东西–作用域链
代码1:
function test1(){
var a=100;
function test2(){
window.alert(a);
}
test2();
}

test1();//100

运行结果是:100;

为什么呢?当我们调用一个函数的时候,那么分为两个过程:
1.编译过程(声明变量,声明函数,语法检查,语义检查,代码优化….等等)
2.执行过程(变量赋值,语句执行…等等);那么 ,我们来分析一下 test1()函数执行过程吧
编译过程:声明了局部变量a 函数test2
执行过程:给局部变量a赋值,执行函数test2(调用过程一样)

问题是函数test2执行过程中的变量a是谁的呢?原来,当test2编译时候,当遇到没有没有的变量 ,那么它会沿着一条链路(作用域链)去寻找,由于test2是被test1嵌套的,那么test2没有变量a,就到它上一层关系中寻找,即test1,得以找到变量a,如果test1也没有,那么再到上一层关系(window顶级对象寻找),如果在win顶级对象中不能寻找得到想要的变量,那么将报错并停止本块js代码块的执行。(不会影响后面的js代码块);

************
注意 :编译的过程中产生错误 那么本块js代码将不再执行 如果下面还有js代码块 继续执行下面的js代码块
<script>
..(); //编译过程中 语法检查错误 所以本块js代码不再执行
window.alert(“1111″);
</script>

<script type>
window.alert(“hello”); //程序向下执行到这段代码块 编译成功 执行代码
</script>

************

闭包:
代码2:
function test1(){
var num=0;
function test2(){
window.alert(++num);
}
return test2;
}

var aa =test1();

aa();//1

aa();//2
代码分析:
执行函数test1并把test2返回赋值给aa;由于把test2赋值给aa,实质是把test2对应的内存地址赋值给aa,由于test2是基于test1存在的,那么,内存中,test2是不会被销毁的,test1也不会销毁。下面执行aa,实质上是执行test2(),函数在执行过程中,由于在自身找不到变量num,那么将在上一层关系中寻找,window.alert(++num) ,++num 是表示 先自加再返回,自加过程中,那么它是对上一层关系中的num起作用,也就是test1中的num在自加而已,每次执行后,将对num进行保存。(注意:这里num并不是test2的变量,它执行过程中,由于它是对上一级关系的变量num发生作用而已,如果函数中有自有的变量,那么还是将遵守函数执行规则);

再一次执行aa(),那么依然是遵照以上流程,由于在上一次执行过程中,num值得到了改变,那么它得到的是改变后的值。该函数执行中,再一次对该变量进行改变,并保存在函数test1中;

0 0
原创粉丝点击