JS进阶 | 作用域(链)以及变量提升

89 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情

在 JS 中作用域和变量是基础的概念,今天来说说作用域(链)以及变量提升

作用域:

作用域,就是变量的作用范围。定义的位置决定了函数的作用域。

在 JS 中作用域分为三种,分别是:

  • 全局作用域

    <script> 中的 JS 代码

  • 函数作用域(局部)

    函数内部定义的变量都属于函数作用域

  • 块级作用域

    ES6,使用 let 或 const 关键字声明的变量,会形成块级作用域

Tips:在全局作用域中,没有办法访问到函数作用域中的局部变量(闭包可以访问)。反之,在函数作用域中,可以访问到全局作用域中的变量。

那么在什么情况下会产生作用域链呢?答案是当函数嵌套的时候。

作用域链

当嵌套的函数在其作用域内操作变量的时候,会从当前作用域开始,一层一层向上查找变量,作用域链就是这样形成的。

查找规则:

  • 如果在当前作用域中能找到,就直接使用
  • 如果在当前作用域中找不到,就像上一层作用域进行查找,一层层直到找到为止
  • 如果找到全局作用域时还未找到则会报错

注意

  1. 函数内部和全局有相同名称的变量,会使用函数内的变量
  2. 函数的形参也是局部变量
var a = 1;
function fn() {
  function fn2(a) {
    fn3(a);
    fn3();
  }
  function fn3(a) {
    console.log(a);
  }
  fn2(a);
}
fn();

输出结果

1

undefined

在控制台执行: image.png

变量提升

所有 var 声明的变量和 function 声明的函数,会被在代码执行前提升到当前作用域的最前面(这里注意区分function和函数表达式)。

在 JS 中有变量提升,也有函数提升:

  • 同名的函数和变量,在变量和函数提升时,以函数为主
  • 同名的函数,在提升时,后面的会覆盖前面的```
  • 函数表达式不进行提升

image.png

例子

console.log(a);
a();
function a() {
  console.log("11111");
}
var a = 33333;
function a() {
  console.log("22222");
}
var b = a;
console.log(b);

输出结果

image.png