作用域Scope
什么是作用域?
变量,函数能访被访问的位置范围
在JavaScript中,有俩种作用域
-
全局作用域(Global)
-
局域作用域(Local)
- 函数作用域
- 块级作用域(ES6+才有的)
全局作用域
当我们说道全局作用域的时候,指的是没有被包含在{}的代码。能被任何位置的代码访问。
const name='jojo'
if(true){
console.log(name); //这里可以访问name
}
function say(){
console.log(name); //这里也可以访问name
}
//say 函数也能被任何地方的代码调用
注意
在if,for语句中使用var声明的变量,也能被任何位置的代码访问。因为var声明的变量存在提升(# Hoisting)
这也是为什么在es6以前,没有块级作用域。
if(true){
var name='jojo';
}
console.log(name) //jojo
局部作用域
局部作用域、在es6以前指的就是函数内部的变量声明,只能在函数内部被访问。
在es6之后,由于新加了const,let变量声明,所以有了块级作用域的作用。在 ES6 之前,我们只有一个关键字来定义变量“var”。所以那时我们有一种类型的局部作用域,它是由函数创建的。在 ES6 中,他们想让代码更加模块化,所以他们增加了两个关键字来声明一个变量“let”和“const”。用“let”和“const”声明的变量遵循所有括号并且不能从外部访问。通过这种方式,使用“let”和“const”我们现在可以拥有块作用域。同样对于 ES6,使用“let”和“const”是最好的声明变量的方式。
let 语句声明一个块级作用域的局部变量,并可以初始化为一个值(可选)。
let 跟 const一样。
关于let更多知识,点击访问
作用域链Scope Chain
通过上面的代码
const name='jojo'
if(true){
console.log(name); //这里可以访问name
}
function say(){
console.log(name); //这里也可以访问name
}
say();
当我们运行say函数时,say函数内部需要使用一个name变量。显然,在say函数的作用域内并没有发现name变量。这个时候呢,将尝试从父作用域中寻找个变量,对应这里的就是全局作用域。
还没看明白?下面通过一个列子来解释,解释之前呢,我们先了解几个概念。
- 静态作用域
- 动态作用域
在代码执行的时候,如何确定作用域中变量的值?一般情况分静态作用域,和动态作用。静态作用域关心的是代码声明的位置。动态作用域关心的是函数的调用者的位置。在JavaScript编程中,使用的是静态作用域,作用域的范围跟函数的声明位置有关。
const name='jojo'
function word(){
console.log(name); //jojo
}
function say(){
const name='wwbb'
word();
}
say();
上面代码可以看出,word确定变量name的值的时候,选择的是全局作用域的name变量,而在调用word函数的say作用域中声明的name变量,没有被使用。
总结
- JavaScript有俩种作用域,全局作用域和局部作用域。局部作用域分为函数作用域,和块级作用域
- JavaScript是静态作用域,作用域链的关系跟函数,变量的声明位置有关。