持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
在 JS 中作用域和变量是基础的概念,今天来说说作用域(链)以及变量提升
作用域:
作用域,就是变量的作用范围。定义的位置决定了函数的作用域。
在 JS 中作用域分为三种,分别是:
-
全局作用域
如
<script>中的 JS 代码 -
函数作用域(局部)
函数内部定义的变量都属于函数作用域
-
块级作用域
ES6,使用 let 或 const 关键字声明的变量,会形成块级作用域
Tips:在全局作用域中,没有办法访问到函数作用域中的局部变量(闭包可以访问)。反之,在函数作用域中,可以访问到全局作用域中的变量。
那么在什么情况下会产生作用域链呢?答案是当函数嵌套的时候。
作用域链
当嵌套的函数在其作用域内操作变量的时候,会从当前作用域开始,一层一层向上查找变量,作用域链就是这样形成的。
查找规则:
- 如果在当前作用域中能找到,就直接使用
- 如果在当前作用域中找不到,就像上一层作用域进行查找,一层层直到找到为止
- 如果找到全局作用域时还未找到则会报错
注意
- 函数内部和全局有相同名称的变量,会使用函数内的变量
- 函数的形参也是局部变量
var a = 1;
function fn() {
function fn2(a) {
fn3(a);
fn3();
}
function fn3(a) {
console.log(a);
}
fn2(a);
}
fn();
输出结果:
1
undefined
在控制台执行:
变量提升
所有 var 声明的变量和 function 声明的函数,会被在代码执行前提升到当前作用域的最前面(这里注意区分function和函数表达式)。
在 JS 中有变量提升,也有函数提升:
- 同名的函数和变量,在变量和函数提升时,以函数为主
- 同名的函数,在提升时,后面的会覆盖前面的```
- 函数表达式不进行提升
例子
console.log(a);
a();
function a() {
console.log("11111");
}
var a = 33333;
function a() {
console.log("22222");
}
var b = a;
console.log(b);
输出结果: