JS的作用域和作用域链
什么是作用域?
作用域是在程序运行时代码中的某些特定部分中变量、函数和对象的可访问性。
从使用方面来解释,作用域就是变量的使用范围,也就是在代码的哪些部分可以访问这个变量,哪些部分无法访问到这个变量,换句话说就是这个变量在程序的哪些区域可见,如下代码:
什么是作用域链?
多个作用域对象连续引用形成的链式结构。
使用方面解释:当在Javascript中使用一个变量的时候,首先Javascript引擎会尝试在当前作用域下去寻找该变量,如果没找到,再到它的上层作用域寻找,以此类推直到找到该变量或是已经到了全局作用域,如果在全局作用域里仍然找不到该变量,它就会直接报错。
上面的例子说明函数的作用域是在函数定义的时候就确定了,而不是在函数执行的时候,这时候可能会联想到执行上下文,执行上下文是在函数执行时确定的。执行上下文最明显的就是this的执向是执行时确定的,而作用域访问的变量是编写代码的结构确定的。
作用域和执行上下文最大的区别就是:执行上下文在运行时确定,随时可能改变;作用域在定义时就确定,并且不会改变。
作用域分类?
作用域分类有全局作用域、局部作用域和ES6的块级作用域,块级作用域可以通过let和const关键字来创建
- 全局作用域简单来说就是在该作用域内声明的变量任意地方都可以访问到
- 函数作用域简单来说就是函数内部可以访问和使用变量和方法,函数外部无法访问和使用
-
块级作用域块语句(
{}中间的语句),如if和switch条件语句,for和while循环语句,不同于函数,它们不会创建一个新的作用域;但是ES6及之后的版本,块语句也会创建一个新的作用域, 块级作用域可通过新增命令let和const声明,所声明的变量在指定块的作用域外无法被访问。 -
声明变量不会提升到代码块顶部,即不存在变量提升
-
禁止重复声明同一变量
-
for循环语句中()内部,即圆括号之内会建立一个隐藏的作用域,该作用域不属于for后边的{}中,并且只有for后边的{}产生的块作用域能够访问这个隐藏的作用域,这就使循环中 绑定块作用域有了妙用