JS中的作用域与作用域链

2,793 阅读2分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。

前言

  • Hello,大家好,我是前端沸人vike
  • 今天一起来聊一聊Js中的作用域和作用域链

作用域

  • 简单理解: 变量可以使用的范围
  • 作用域与作用域之间互不干扰
  • 作用域的分类
    • 全局作用域
      • 在全局可以访问的变量 可以重复使用 但会污染全局环境 不建议使用
    var a = 1
    console.log(window.a) // 1
    // 全局变量挂载在window上
    
    • 函数作用域
      • 在局部可以访问的变量 不可以重复使用 不会污染全局
      • 函数的形参也属于局部变量
    let fn = (x)=> {
     var a =  1; // 变量只存在于函数
     b++;
     console.log(a,b);
    }
    var b = 1
    fn(b) // 1,2
    console.log(a,b) //  ReferenceError: a is not defined, 2
    
  • 开胃小菜
    • 有人会好奇的问:es6不是新增了块级作用域吗?
    • 解答: JS里从来不存在块级作用域 块级作用域是一个伪命题
    • 先看看ES5实现块级作用域
    • ES5模拟块级作用域本质上是匿名函数立即执行
    // ES5 模拟块级作用域
    (function () {
        var x = 1;
        console.log(x) // 1
    } ())
    
    console.log(x) // ReferenceError: x is not defined
    
    • ES6 块级作用域实际上也是立即执行的匿名函数

作用域链

  • 作用域链就是变量查找的过程
  • 示例代码
    • 函数fn使用的变量a在当前作用域中不存在
    • 向上级作用域(全局)进行查找 找到a变量
    var a = 1;
    function fn() { 
        console.log(a)
    }
    fn() // 1
    

作用域链.jpg

  • 特例:
    • 怎么在函数作用域声明全局变量?
    • 此代码仅限演示使用 开发中禁止使用
    • 在函数中使用未定义变量赋值 会转换成在全局声明a变量
    function fn () {
        a = 1;
    }
    fn();
    console.log(a); // 1
    

var & let 冷知识

  • JS中不存在堆和栈的概念

  • JS 底层是关联数组

    // 示例代码
    var y = 1;
    y // 1
    window.y // 1
    window['y'] // 1
    
  • var 和 let 声明的变量不处于同一对象中

    • let 处于script中 所以window.w 是undefined
    • var 处于window中
    let w = 1;
    var a = 2;
    debugger; // 调试程序
    

debugger.png

结语

  • 谢谢大佬们阅读,感觉文章写的还不错的话,留下个赞吧!