最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

javascript作用域链与执行环境

来源:懂视网 责编:小采 时间:2020-11-27 20:23:29
文档

javascript作用域链与执行环境

javascript作用域链与执行环境:作用域、作用域链、执行环境、执行环境栈以及this的概念在javascript中非常重要,本人经常弄混淆,这里梳理一下;局部作用域函数内部的区域,全局作用域就是window;作用域链取决于函数被声明时的位置,解析标识符的时候就先找当前作用域,再向外查找,直到全
推荐度:
导读javascript作用域链与执行环境:作用域、作用域链、执行环境、执行环境栈以及this的概念在javascript中非常重要,本人经常弄混淆,这里梳理一下;局部作用域函数内部的区域,全局作用域就是window;作用域链取决于函数被声明时的位置,解析标识符的时候就先找当前作用域,再向外查找,直到全

作用域、作用域链、执行环境、执行环境栈以及this的概念在javascript中非常重要,本人经常弄混淆,这里梳理一下;

  1. 局部作用域函数内部的区域,全局作用域就是window;

  2. 作用域链取决于函数被声明时的位置,解析标识符的时候就先找当前作用域,再向外查找,直到全局,这样一个顺序;和函数在哪里调用无关;

  3. 执行环境就是函数可访问的数据和变量的集合,也就是函数的作用域链上的所有数据和变量;

  4. 执行环境栈就是根据代码执行顺序,各执行环境按照栈的形式逐层访问,并且用完了退出来扔掉;如果当前执行环境(存放当前作用域链里的数据和变量)找不到变量,那就是找不到了,不会往之前的那个执行环境查找,它和作用域链是不同的;

作用域

  JavaScript没有块级作用域的概念,只有函数级作用域:变量在声明它们的函数体及其子函数内是可见的。

  作用域就是变量和函数的可访问范围,控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域。

  • 变量没有在函数内声明或者声明的时候没有带var就是全局变量,拥有全局作用域;

  •  <script type="text/javascript">
     function test1(){
     a = 1;//全局变量,只有在当前函数运行时,才有效 }
     test1();
     console.log(a);//1 注意test1函数必须运行,不然找不到a
     </script>
  • 全局变量可以当做window对象的属性用,他们是一样的;

  •  <script type="text/javascript"> 
     var b = 1;//全局变量 
     console.log(b === window.b);
     //true 全局变量可以当做window对象的属性用,他们是一样的;
     </script>
  • window对象的所有属性拥有全局作用域,在代码任何地方都可以访问;

  • 函数内部声明的变量就是局部变量,只能在函数体内使用,函数的参数虽然没有使用var但仍然是局部变量。

  •  <script type="text/javascript"> 
     var c = 1;//全局变量// 
     console.log(d);//ReferenceError: d is not defined 引用错误,当前作用域就是最外层作用域,依然找不到d
     function test2(d){
     console.log(c);
     //1 全局变量,哪都可以访问;(先找当前作用域,找不到,就向外层作用域找,直到window最外层,找到了) console.log(d);//3 形参是局部变量,只有当前作用域下可以访问 }
     test2(3); 
     </script>

    作用域链

      作用域链取决于函数被声明时的位置,解析标识符的时候就先从当前作用域开始找,在当前作用域中无法找到时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量,或抵达最外层的作用域(也就是全局作用域)为止;它的路线已经被定死了,和函数在哪里运行无关;

     <script type="text/javascript">
     var a = 1; 
     var b = 2; 
     var c = 3; 
     var d = 4; 
     function inner(d) {//它的作用域链是inner---全局
     var c = 8;
     
     console.log(a);//1 当前作用域找不到a,去全局作用域找到了a=1 console.log(b);//2 当前作用域找不到b,去全局作用域找到了b=2 console.log(c);//8 当前作用域找到了c=8 console.log(d);//7 当前作用域找到了d=7,形参也是局部作用域
     // console.log(e);//ReferenceError: e is not defined 引用错误,找不到e, 它的作用域链是inner---全局 console.log(a+b+c+d);//18 } function outter(e) { var a = 5;//inner()的作用域链是inner---全局,所以这个a相当于无效
     var b = 6;//inner()的作用域链是inner---全局,所以这个a相当于无效 inner(7);
     }
     outter(999);//这个999无效,里面的e根本找不到
     </script>
  • 在多层的嵌套作用域中可以定义同名的标识符,这叫作“遮蔽效应”,内部的标识符“遮蔽”了外部的标识符

  • 通过window.a这种技术可以访问那些被同名变量所遮蔽的全局变量。但非全局的变量如果被遮蔽了,无论如何都无法被访问到;

  •  <script type="text/javascript">
     var a = 'Lily'; 
     var b = 'Lucy'; 
     function outer() { 
     var b = 'Jesica'; 
     var c = 'Susan'; 
     function inner(c) {
     console.log(a);//Lily 
     console.log(window.b);//Lucy 
     console.log(b);//Jesica 
     console.log(c);//Jenifer 
     }
     inner('Jenifer');
     }
     outer(); 
     </script>

    执行环境

      执行环境(execution context),也叫执行上下文。每个执行环境都有一个变量对象(variable object),保存函数可访问的所有变量和数据(也就是函数的作用域链上的所有数据和变量)。我们的代码访问不到它,它是给引擎使用的;

      执行环境栈,当执行进入一个函数时,函数的执行环境就会被推入一个栈中。而在函数执行完之后,栈将其执行环境移除,它里面的变量和数据会被标记清除,等待垃圾回收,再把控制权返回给之前的执行环境。javascript程序中的执行正是由这个机制控制着;

      需要注意的是如果当前执行环境(存放当前作用域链里的数据和变量)找不到变量,那就是找不到了,不会往之前的那个执行环境查找,和作用域链是不一样的;

      代码的执行顺序也不全是一行一行的执行,而是和函数的调用顺序有关:

  • 代码进入全局执行环境,全局执行环境放入环境栈;

  • 当执行到一个函数时,就把这个函数的执行环境推入到环境栈顶端,之前的执行环境往后;

  • 全局执行环境最先进入,所以一直在底端;就和栈的概念差不多;

  • 函数执行完之后,再把它的执行环境从作用域链顶端移除,它保存的数据和函数都被标记清除,等待垃圾回收;

  • 控制权交给之前的执行环境,继续往下执行;

  • 当页面关闭时,全局执行环境才销毁;

  • 代码执行进入全局执行环境,并对全局执行环境中的代码进入声明提升;    

  • 执行第2行,赋值a=1; 然后第3行赋值b=2; 然后第4行赋值c=3; 然后第5行赋值d=4;

  • 执行第20行,调用outer(999)函数,然后进入outer(999)函数执行环境,声明提升,并将实参999传给形参e;现在环境栈中有两个执行环境,outer(999)是当前执行环境;

  • 执行第16行,赋值a=5; 然后第17行赋值b=6;    

  • 执行第18行,调用inner(7)函数,然后进入inner(7)函数执行环境,声明提升,并将实参7传给形参d;

  • 执行第7行,赋值c=8; 然后运算并输出;

  • 代码优化

      由于在作用域链上查找变量是需要消耗性能的,我们应该尽快的找到变量,所以在函数多层嵌套的时候,我们应尽可能的使用函数内部的局部变量;

      我们在函数内部使用全局变量可以说是一种跨作用域操作,如果某个跨作用域的值在函数的内部被多次使用,那么我们就把它存储到局部变量里,这样可以提高性能。

    文档

    javascript作用域链与执行环境

    javascript作用域链与执行环境:作用域、作用域链、执行环境、执行环境栈以及this的概念在javascript中非常重要,本人经常弄混淆,这里梳理一下;局部作用域函数内部的区域,全局作用域就是window;作用域链取决于函数被声明时的位置,解析标识符的时候就先找当前作用域,再向外查找,直到全
    推荐度:
    标签: js 环境 javascript
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top