搜索
写经验 领红包
 > 自然

js中什么是作用域(js作用域、作用域链)

导语:JS基础系列—聊聊作用域

在JS编程中,最常用到的一个操作,就是访问变量。而当我们想要访问变量时,JS会在一个空间中查找是否有该变量,而这个空间我们就可以称之为作用域。

每次进入一个执行函数,就会新生成一个执行环境,并push到执行栈,该执行环境中会有当前作用域,又因为函数设计师可以访问到外部的变量,也就是外部作用域,如果函数存在嵌套,就有一层又一层的外部作用域,这也就产生了作用域链(最外层的是全局作用域,任何全局变量在任何地方都可以访问到),要注意的是作用域链是在声明时已经确定的,而不是在运行时确定。

接下来我们就好好来了解下作用域相关知识点

1、作用域初体验

如下代码

function test(){var name=;  console.log(name);}test();console.log(name);

当进入test方法时,新的执行环境(这里我们将其命名为A)产生,并压入执行栈,而在该执行环境也开辟了一个新的作用域空间。

因为声明了name变量,所以此时作用域中有个name变量,并后来为这个变量赋值为,所以后续打印到出来了(this变量我们前面系列也提到,这里可以看到在作用域中也存储着该变量),如下图:

而到test执行完之后,执行环境A被POP出栈,执行环境A被销毁,此时作用域就是全局作用域,这里的name访问就和上图的不一致了,因为全局作用域有个name变量,所以name就访问到全局的name变量

2、作用域链

function test(){  var nameTest=;  function inner(){      var nameInner=;      function inner2(){          var nameInner2=;          console.log(nameInner2,nameInner,nameTest)      }      inner2();            console.log(nameInner2,nameInner,nameTest)  }  inner();}test();console.log(name);

当我们在inner2执行断点时,发现此时调用栈有多个执行环境,而在最里面的函数中,除了访问到自己变量nameInner2时,也可以访问到外层变量,以及外2层的变量,当然外几层都可以

而在inner函数中,无法访问到nameInner2,因为外部的无法访问到内部的

这也就是我们常说的作用域链

3、作用域链是函数定义时声明

代码如下

var name=function test(){  var nameTest=;  test2();}function test2(){  console.log(nameTest,name)}test();

当我们执行test2时,你觉得会打印出什么[what][what],会是JX新,test吗??

不会,实际上是报错了。因为test2定义时所声明的代码位置就决定其作用域链,就只能是其外部而非其他同级函数包裹的变量(比如test作用域中的nameTest),即使test2执行时,test的执行环境还没销毁,如下图(注意作用域链和执行栈无关哦)

本文内容由快快网络小梓创作整理编辑!