欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

javascript作用域链与执行环境的详细介绍

来源:本站整理 作者:佚名 时间:2017-07-03 TAG: 我要投稿

前言:这是笔者学习之后自己的理解与整理。如果有错误或者疑问的地方,请大家指正,我会持续更新!
作用域、作用域链、执行环境、执行环境栈以及this的概念在javascript中非常重要,本人经常弄混淆,这里梳理一下;
局部作用域函数内部的区域,全局作用域就是window;
作用域链取决于函数被声明时的位置,解析标识符的时候就先找当前作用域,再向外查找,直到全局,这样一个顺序;和函数在哪里调用无关;
执行环境就是函数可访问的数据和变量的集合,也就是函数的作用域链上的所有数据和变量;
执行环境栈就是根据代码执行顺序,各执行环境按照栈的形式逐层访问,并且用完了退出来扔掉;如果当前执行环境(存放当前作用域链里的数据和变量)找不到变量,那就是找不到了,不会往之前的那个执行环境查找,它和作用域链是不同的;
this是一个对象,它取决于是谁执行的,谁执行那就是谁;(this的概念还是不太清楚,这里写的有点万金油,过两天再来修正)
作用域
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程序中的执行正是由这个机制控制着;
需要注意的是如果当前执行环境(存放当前作用域链里的数据和变量)找不到变量,那就是找不到了,不会往之前的那个执行环境查找,和作用域链是不一样的;
代码的执行顺序也不全是一行一行的执行,而是和函数的调用顺序有关:
代码进入全局执行环境,全局执行环境放入环境栈;
当执行到一个函数时,就把这个函数的执行环境推入到环境栈顶端,之前的执行环境往后;

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载