静态作用域
什么是作用域?域是范围,字面意思就是代码起作用的范围。
JavaScript是静态作用域,也叫字面作用域,根据代码书写位置来确定变量的引用规则。例如:
var value = 1
function inner() {
console.log(value)
}
function outer() {
var value = 2
inner();
}
outer(); // 打印结果为1
如果是动态作用域,就会先从inner函数内部先查找value变量,没有就查找调用inner函数的outer函数,查找到了就会打印出2
函数作用域和块级作用域
ES5只有全局作用域和函数作用域,ES6新增了块级作用域。
为什么需要引入块级作用域?因为函数作用域有它的局限,例如
var a = 1
function foo() {
console.log(a)
if (true) {
var a = 5 // 定义同名变量
}
}
foo();
这里会输出undefined
,为什么呢?
调用foo函数后,会先在函数内部查找变量a,在console.log打印变量a的时候,发现了变量a的声明,但是没有赋值,赋值的动作是在打印后,所以就输出undefined
。
这个执行逻辑涉及到了变量提升,var a = 5
这行代码分成了两部分,将代码的声明部分提升到了作用域的顶部,赋值部分放在书写代码部分。
为了避免出现变量被覆盖,所以就引入了块级作用域
var a = 1
function foo() {
console.log(a)
if (true) {
let a = 5 // 用let定义同名变量
}
}
foo();
同样的栗子,这里使用let定义块级作用域,意思就是let定义的变量a只在if这个块级起作用,这样就会打印输入1
作用域链
例如上图,变量取值的逻辑是这样,先从当前作用域查找变量的值,如果没有查找到,就从上级变量查找,这样的查找过程形成了一个链条,这个链条就是作用域链
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。