js---作用域链,立即执行函数,闭包
龚超 2018-03-28 来源 : 阅读 1778 评论 0

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
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论
本文作者 联系TA

擅长针对企业软件开发的产品设计及开发的细节与流程设计课程内容。座右铭:大道至简!

  • 370
    文章
  • 44696
    人气
  • 83%
    受欢迎度

已有24人表明态度,83%喜欢该老师!

进入TA的空间
求职秘籍 直通车
  • 资料领取 资料领取 资料领取
  • 答疑解惑 答疑解惑 答疑解惑
  • 技术交流 技术交流 技术交流
  • 职业测评 职业测评 职业测评
  • 面试技巧 面试技巧 面试技巧
  • 高薪秘笈 高薪秘笈 高薪秘笈
TA的其他文章 更多>>
WEB前端必须会的基本知识题目
经验技巧 93% 的用户喜欢
Java语言中四种遍历List的方法总结(推荐)
经验技巧 91% 的用户喜欢
Java语言之SHA-256加密的两种实现方法详解
经验技巧 75% 的用户喜欢
java语言实现把两个有序数组合并到一个数组的实例
经验技巧 75% 的用户喜欢
通过Java语言代码来创建view的方法
经验技巧 80% 的用户喜欢
其他海同师资 更多>>
吕益平
吕益平 联系TA
熟悉企业软件开发的产品设计及开发
孔庆琦
孔庆琦 联系TA
对MVC模式和三层架构有深入的研究
戴懿颢​
戴懿颢​ 联系TA
20年+嵌入式开发经验,精多语言 / 云 / 安全 / 数据库
郭自琦
郭自琦 联系TA
16年物联网经验,涉多项目,多校授课,出版书籍并研发IT教程
余承民
余承民 联系TA
8年开发+5年教学经验,指导数千名学员高薪就业
经验技巧30天热搜词 更多>>

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved