Revan1i

vuePress-theme-reco revan1i    2019 - 2020
Revan1i Revan1i

Choose mode

  • dark
  • auto
  • light
Home
TimeLine
Category
  • javascript
  • css
  • react
  • js
  • how
  • math
  • regexp
  • algorithm
  • feeling
Tag
Contact
  • GitHub
author-avatar

revan1i

25

文章

20

标签

Home
TimeLine
Category
  • javascript
  • css
  • react
  • js
  • how
  • math
  • regexp
  • algorithm
  • feeling
Tag
Contact
  • GitHub

Javascript基础之词法作用域和动态作用域

vuePress-theme-reco revan1i    2019 - 2020

Javascript基础之词法作用域和动态作用域


revan1i 2019-10-19 12:03:41 javascript base

# 作用域

作用域(scope)是变量与函数在程序中的可见性范围。作用域控制着当前执行代码对变量与函数的访问权限。 作用域有两种常见的模型,一种叫做词法作用域(Lexical Scope), 一种叫做动态作用域(Dynamic Scope)。JavaScript 采用的是词法作用域,也是静态作用域。

# 词法作用域

词法作用域是在书写代码或者定义时确定的,而动态作用域是在运行是确定的,前者关注函数在何处声明,而动态作用域关注函数从何处调用。

举个例子说明:

var a = 1;

function foo() {
  console.log(a)
}

function bar() {
  var a = 2;
  foo()
}

bar()
1
2
3
4
5
6
7
8
9
10
11
12

因为 Javascript 是采用词法作用域,所以 bar 函数执行后 foo 函数执行,foo 函数从内部查找是否有局部变量 a, 如果没有,就根据书写的位置,查找上面一层的代码, 也就是 a = 1, 所以结果打印1。

# 作用域类型

作用域有全局作用域、函数作用域以及ES6之后的块级作用域。

# 全局作用域

在代码中任何地方都能访问到的对象拥有全局作用域。一般情况以下几种情况拥有全局作用域。

  • 最外层函数
  • 所有未定义直接赋值的变量自动声明为全局变量,拥有全局作用域
  • window对象

# 函数作用域

是指声明在函数内部的变量,只在当前函数内部可以访问。内部嵌套的作用域会进行分层,内层作用域可以访问外层作用域的变量,反之则不行

作用域访问:③ -> ② -> ①, 不可逆。
可以理解作用域访问过程是,在一个建筑里面有一部只能升不能降的电梯,只能向上查找直到全局作用域。

# 块级作用域

块级作用域可以通过 let 和 const 声明,声明的变量在指定块的作用域外无法被访问。花括号{}中间内的块语句也是是块级作用域。

# 动态作用域

动态作用域中,变量的值与定义无关,由运行是决定。 bash 就是动态作用域,可以尝试将下面代码保存为 scope.bash 文件,用命令 bash ./scope.bash 运行,看看打印的值是多少

a=1
function foo() {
  echo $a;
}
function bar() {
  local a=2;
  foo;
}
bar
1
2
3
4
5
6
7
8
9

最终的结果是2。

# 参考

1、从上下文,到作用域
2、JavaScript深入之词法作用域和动态作用域
3、深入理解JavaScript作用域和作用域链