JavaScript的作用域链和闭包

2021-06-03 02:04

阅读:540

标签:通过   nav   方案   作用域   图片   变量   直接   闭包   语句   

一、闭包的概念

       函数套函数,子级函数里面用了父级函数的变量,这种情况就属于闭包。

二、作用域的概念

       假设一段代码被保存在单独的js文件中,当某个包含该js文件的网页运行在浏览器中的时候,JavaScript已经预先创建好一个全局作用域,该作用域包含一个全局上下文,该上下文包含window、navigator等内置的全局对象。

       如下代码,当执行到第3行并赋值a=1时,全局上下文(全局变量)就包含了"a"这个变量,接下来的语句就能使用该变量。 当执行到第4行时函数"fun1"也被加到全局上下文中。

 1     // 使用闭包技术的JavaScript函数
 2     // 函数一:
 3     var a = 0;
 4     function fun1() {
 5         var a = 1;
 6         function sum(b) {
 7             return a+b;
 8         }
 9         return sum(0);
10     }
11     var c1 = fun1(0);
12     // 函数二(匿名函数):
13     var a = 0;
14     var c2 = (function(b){
15         var a = 1;
16         function sum(b) {
17             return a+b;
18         }
19         return sum(b);
20     })(0);
21     console.log(c1,c2); // 1  1

        在“fun1”函数中,同样会有一个属于“fun1”的作用域也就是上下文,该上下文同时也会指向全局上下文,同理到函数“sum”内部时,执行环境也会为它建立上下文,同时也会指向它的父上下文。

技术图片

         当第11行调用fun1函数时,在sum函数内部执行环境检查当前的上下文,查找有无变量“a”,当然在此例中没找到,于是他会在父上下文中查找,很明显父上下文fun1中有“a”,所以a=1,如果fun1中没有“a”,会继续向上在全局作用域链中查找。

         整个变量查找的过程讲完了,接下来说一下"函数二"比“函数一”好的地方,fun1在全局上下文中很可能会导致命名冲突问题,像函数二那样使用匿名函数直接调用,这样这个函数就不会污染到全局空间。

         到这里,大家是否理解了上面所述的作用域的一些概念,接下来看下面一道例题。

三、例题练习

1 for (var i = 0; i ) {
2     setTimeout(() => {
3         console.log(i);
4     })
5 }

        请问上述代码打印出的结果是是啥?

        技术图片

        这里不卖关子了结果打印出6个6。

        原因是:打印i的时候在setTimeout函数内部没有找到i变量,在父级作用域里找到i,此时由于异步执行这时的i已经变成了6.

        那么如何修改该函数使得打印出的结果是0——5呢?

 1    // 方案一:
 2     for (var i = 0; i ) {
 3         setTimeout((i) => {
 4             console.log(i)
 5         },400,i)
 6     }
7 // 方案二: 8 for (var i = 0; i ) { 9 (function(i){ 10 setTimeout(() => { 11 console.log(i) 12 },400) 13 })(i); 14 }

        方案一:既然setTimeout上下文中没有i,那么就通过setTimeout函数的第三个参数将i传进去,使得在setTimeout内部作用域中直接找到i。

        方案二:使用闭包将i传到匿名函数中,setTimeout通过父级上下文(匿名函数)中找到传进来的i。

 

  

 

        

 

       

 

JavaScript的作用域链和闭包

标签:通过   nav   方案   作用域   图片   变量   直接   闭包   语句   

原文地址:https://www.cnblogs.com/tsl0324/p/14683375.html


评论


亲,登录后才可以留言!