JavaScript-什么是作用域,作用域和作用域链,js没有块级作用域
作用域概述
在任何编程语言中都有作用域的概念,简单来说,所谓的作用域就是变量可作用的范围(可被访问到的区域)
在 JavaScript 中有两种作用域类型,一种是全局作用域另一种是局部作用域
想要理解作用域就必须要理解全局变量和局部变量
全局变量
在网页的所有脚本和函数都能够访问到的变量就是全局变量
如何定义全局变量:
- 在函数外部定义的变量,就是 全局变量
- 在函数内部,省略关键字
var
定义的变量也是全局变量
全局变量的特点:
- 全局变量 既可以在函数外使用,也可以在函数内部使用。
- 全局变量 在网页关闭时,会自动清除(销毁释放空间)。
示例:
// 在函数外定义了全局变量
var num = 66;
// 修改前
console.log(num)
// 定义函数
function func() {
// 在函数中使用全局变量
num += 10;
console.log('在函数中修改了全局变量,结果为:' + num)
}
// 调用函数,修改全局变量
func()
// 全局函数是否被修改
console.log(num);
局部变量
只能在固定范围内访问的变量就称之为局部变量,最常见的就是在函数中定义的变量只能在函数中访问
如何定义局部变量:
- 在函数内部定义的变量就是局部变量
局部变量的特点
- 局部变量 只能在函数内部使用,在函数外部无法访问。
- 局部变量 在函数执行完毕就消失了,所以局部变量更节省内存空间,函数中的形参也是局部变量。
示例:
// 函数的形参也属于局部变量
function func(arg) {
// 在函数中定义了局部变量
var num = arg + 66;
// 打印局部变量
console.log('局部变量 num = ' + num)
}
// 调用函数
func(123)
// 是否能使用局部变量(报错)
console.log(arg)
块级作用域
任何一对花括号 {} 中的代码都属于一个块,在这之中定义的所有变量在 {} 外都是不可见的,我们称之为块级作用域。
在 es6 之前没有块级作用域的的概念,只有函数作用域;es6 中新增了块级作用域;现阶段可以认为 JavaScript 没有块级作用域
词法作用域
词法作用域就是定义在词法阶段的作用域;变量的作用域是在代码中定义时决定的而不是执行时决定,也就是说词法作用域取决于源码,通过静态分析而确定,因此词法作用域也叫做静态作用域。
在 js 中词法作用域规则:
- 函数允许访问函数外的数据
- 整个代码结构中只有函数可以限定作用域
- 作用域规则首先使用提升规则分析
- 如果当前作用域中有变量名了, 就不考虑外面的了(就近原则)
作用域链
只要是代码代码,就至少有一个作用域,即全局作用域。,写在函数内部的是局部作用域,没有写在函数内部就在全局作用域中;如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域;
将这样的所有的作用域列出来,就可以形成一个结构: 函数内指向函数外的链式结构。
内部函数可以访问外部函数变量,通过链式查找决定哪些数据能被内部函数访问,就称作作用域链。
所谓的链式查找就是当前的作用域中没有需要的变量就会去其上一级作用域中查找,如果还没就继续向上查找,直到查到顶层作用域中还没有就认为这个变量未声明
var num = 999;//该变量与函数f1为零级作用域
function f1(){
var num = 11;//该变量与函数f2为一级作用域
function f2(){
var num = 22;//该变量与函数f3为二级作用域
function f3(){
var num = 33;//该变量与函数f4为三级作用域
function f4(){
var num = 44;//四级作用域
//输出的结果为f4函数中的 num 的值,当该作用域中没有变量 num 时,会向上一级作用域查找若没有再向上一级查找;
// 以此类推,直到零级作用域,若还没有则会报错;
// 换句话说,本级作用域中的变量可为下级作用域所用
console.log(num);
}//end f4
}//end f3
}//end f2
}//end f1
还没有评论,来说两句吧...