1.作用域链----函数定义时会获得父级的作用域链的值放在自己的[[Scopes]]属性中,[[Scopes]]是系统自带的隐式属性,通过console.dir(函数名) 可以查看这个函数的作用域链,即[[Scopes]]。任何函数都至少会有Global的作用域,嵌套越深,作用域链越长。当执行函数的前一刻时,会生成当前函数的独一无二的AO,添加到自己的作用域链中。
注意:任何函数只能使用自己作用域链里的东西,并且是按照作用域链中的由顶向下查看(顺序:自己的作用域--父级作用域---...---Gobal 也就是说每次添加都是在第一位添加,其他已经存在的顺次向下移),一旦找到就停止寻找。
2.立即执行函数(针对初始化功能使用的函数,也可以在项目中起区块作用,避免团队变量函数名称重复相互影响)
[javascript] view plain copy
1. (function a(){console.log(1)}());//1 再调用a()---报错
2. (function b(a,c){console.log(a,c)})(1,2);//1 2 再调用b()---报错
3. //所以函数名失去意义,上面的函数和下面的函数是作用相同的
4. (function (){console.log(1)}());//1
5. (function (){console.log(2)})();//2
6.
7. //<span style="color:#ff0000;">函数只要变成表达式的形式</span>,定义的时候而不是执行的时候,就会发生失去函数名
8. +function c(){console.log(11)}();//报错---c is not defined
9.
10. var d=(1+4,2+1);
11. console.log(d) //3 逗号表示计算第一个表达式,然后再计算后一个表达式并且覆盖前一个的结果
[javascript] view plain copy
1. var a=(function aa(){return 1},+function bb(){return 2});
2. console.log(a); //NaN 第二个表达式的结果
3.
4. var a=(function aa(){return 1},function bb(){return 2});
5. console.log(a); //function bb(){return 2} a(); //2bb(); //报错,var a=(function bb(){}) 是表达式,使bb这个名字失去意义
[javascript] view plain copy
1. var cc=1;
2. if(function c(){}){//除了0 undefined null "" false NaN,其他转成boolean都是true (function c(){})---表达式 导致c相当于未定义
3. console.log(typeof c+cc);//"undefined1" //typeof undefined 只有typeof 一个未声明定义的变量不会报错,是"undefined".
4. }
3.闭包---由于子函数将继承父级AO到自己的作用域链中,当子集函数的生命周期超过父级函数的生命周期时会产生闭包。
通俗点来说,就是父级函数已经执行完毕,父函数执行的过程中:子函数被定义获得父级函数的AO后,被保存到外部。使子函数变成一个与父函数同级但是拥有父函数AO的函数。
闭包的作用:实现公有变量:函数累加器; 可以做缓存,存储结构;封装,属性私有化;模块化开发,防止变量污染。
[javascript] view plain copy
1. function aa(){
2. var num=0;
3. function bb(){
4. num++;
5. console.log(num);
6. }
7. num=123;
8. return bb;
9. }
10. var cc=aa();
11. cc();//124 说明bb和aa是共同使用一个AO,不是复制一份给子函数,是直接公用
12. cc();//125 函数执行的时候回产生唯一的独一无二的AO,但是闭包中使用的父级的AO是确定的,不会再产生新的,因为父级函数并没有执行,所以是125不是124。
13.
14. //闭包的小栗子
15. function bibao(){
16. var arr=[];
17. for(var i=0;i<5;i++){
18. //赋值的时候arr[i]中的i是当前循环的i
19. arr[i]=function(){
20. console.log(i);
21. }
22. }
23. return arr;//最后的arr=[function(){console.log(i)},...,function(){console.log(i)}]
24. }
25. var demo=bibao();
26. demo.forEach(function(item){
27. item();//5..5 结果是5个5 item()是function(){console.log(i)} 此时的i是bibao执行时的独一无二的AO中的i的值,循环结束的时候就已经是5了
28. });
29.
30. //在求索引的时候很容易出现闭包问题,例如
31. function indexBiBao(){
32. var list=document.getElementsByTagName('li');//假设HTML中有一个ul下有四个li 要给li添加点击事件
33. for(var i=0;i<4;i++){
34. list[i].addEventListener('click',function(event){
35. console.log(i);
36. });
37. }
38. }
39. indexBiBao();//最后点击每个li打印的都是4,因为点击事件被绑定在li上,肯定是在外部了,都不在script标签里了。
40. //也就是点击li的时候去执行这个函数,而此时的i应该在indexBiBao执行结束的时候就变成了4
41.
42. //解决方法
[javascript] view plain copy
1. function indexBiBao(){
2. var list=document.getElementsByTagName('li');//假设HTML中有一个ul下有四个li 要给li添加点击事件
3. for(var i=0;i<4;i++){
4. (function(j){
5. //接收形参 类似于var j;
6. //实参赋值 j=i 将当前的i保存在立即执行函数的AO里面,在外面调用时会直接调用父级AO的j
[javascript] view plain copy
1. list[j].addEventListener('click',function(event){
2. console.log(j);
3. });
4. })(i);
[javascript] view plain copy
1. }
2. })
}indexBiBao();//最后点击每个li打印的就是当前的索引值
喜欢 | 0
不喜欢 | 0
擅长针对企业软件开发的产品设计及开发的细节与流程设计课程内容。座右铭:大道至简!
已有24人表明态度,83%喜欢该老师!
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号