作用域
域,表示的是一个范围,作用域,就是作用范围。
作用域说明的是一个变量可以在什么地方被使用,什么地方不能被使用。
块级作用域
javascript中没有块级作用域
{
var num = 123;
{
console.log( num );
}
}
console.log( num );
上面这段代码在JavaScript中是不会报错的,但是在其他的编程语言中(C#、C、JAVA)会报错。
这是因为,在JavaScript中没有块级作用域,使用{}
标记出来的代码块中声明的变量num
,是可以被{}
外面访问到的。
但是在其他的编程语言中,有块级作用域,那么{}
中声明的变量num
,是不能在代码块外部访问的,所以报错。
词法作用域
什么是词法作用域?
词法( 代码 )作用域, 就是代码在编写过程中体现出来的作用范围. 代码一旦写好, 不用执行, 作用范围就已经确定好了. 这个就是所谓词法作用域.
在 js 中词法作用域规则:
-
函数允许访问函数外的数据.
-
整个代码结构中只有函数可以限定作用域.
-
作用域规则首先使用提升规则分析
-
如果当前作用规则中有名字了, 就不考虑外面的名字
JavaScript 预解析
当变量和函数的声明处在作用域比较靠后的位置的时候,变量和函数的声明会被提升到作用域的开头。
作用域链
什么是作用域链
只有函数可以制造作用域结构, 那么只要是代码,就至少有一个作用域, 即全局作用域。
凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。
将这样的所有的作用域列出来,可以有一个结构: 函数内指向函数外的链式结构。就称作作用域链。
绘制作用域链的步骤:
-
看整个全局是一条链, 即顶级链, 记为 0 级链
-
看全局作用域中, 有什么变量和函数声明, 就以方格的形式绘制到 0 级练上
-
再找函数, 只有函数可以限制作用域, 因此从函数中引入新链, 标记为 1 级链
-
然后在每一个 1 级链中再次往复刚才的行为
变量的访问规则
-
首先看变量在第几条链上, 在该链上看是否有变量的定义与赋值, 如果有直接使用
-
如果没有到上一级链上找( n - 1 级链 ), 如果有直接用, 停止继续查找.
-
如果还没有再次往上刚找... 直到全局链( 0 级 ), 还没有就是 is not defined
-
注意,同级的链不可混合查找
声明变量使用`var`, 如果不使用`var`声明的变量就是全局变量( 禁用 )