• JavaScript中作用域问题讨论及示例代码探究


    作用域

    • 作用域指的是一个变量的可见区域
    • 作用域有两种:
      • 全局作用域
        • 全局作用域在网页运行时创建,在网页关闭时销毁
        • 所有直接编写到script标签中的代码都位于全局作用域中
        • 全局作用域中的变量是全局变量,可以在任意位置访问
      • 局部作用域
        • 块作用域
          • 块作用域是一种局部作用域
          • 块作用域在代码块执行时创建,代码块执行完毕它就销毁
          • 在块作用域中声明的变量是局部变量,只能在块内部访问,外部无法访问

    1 函数作用域

    • 函数作用域也是一种局部作用域
    • 函数作用域在函数调用时产生,调用结束后销毁
    • 函数每次调用都会产生一个全新的函数作用域
    • 在函数中定义的变量是局部变量,只能在函数内部访问,外部无法访问
    function fn(){
        let a = "fn中的变量a"
        console.log(a)
    }
    
    fn()
    console.log(a) // undefined 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2 作用域链

    当我们使用一个变量时,JS解释器会优先在当前作用域中寻找变量,就近原则

    • 如果找到了则直接使用
    • 如果没找到,则去上一层作用域中寻找,找到了则使用
    • 如果没找到,则继续去上一层寻找,以此类推
    • 如果一直到全局作用域都没找到,则报错 xxx is not defined

    参照下面的例子理解

    报错的原因看下一节提升相关概念

    let a = 10
    
    {
        console.log(a) // 报错,Cannot access 'a' before initialization
        let a = "第一代码块中的a"
        console.log(a) // "第一代码块中的a"
        {
            console.log(a) // 报错,Cannot access 'a' before initialization
            let a = "第二代码块中的a"
            console.log(a) // "第二代码块中的a"
        }
        console.log(a) // "第一代码块中的a"
    }
    console.log(a) // 10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    let b = 33
    
    function fn() {
        console.log(b) // 报错,Cannot access 'b' before initialization
        let b = 44
        console.log(b) // 44
        function f1() {
            console.log(b) // 报错,Cannot access 'b' before initialization
            let b = 55
            console.log(b) // 55
        }
        f1()
    }
    
    fn()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3 练习

    练习1

    var a = 1
    
    function fn() {
        a = 2
        console.log(a) // 2
    }
    
    fn()
    console.log(a) // 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    练习2

    var a = 1
    
    function fn() {
        console.log(a) //undefined
        var a = 2
        console.log(a) // 2
    }
    
    fn()
    console.log(a) // 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    练习3

    var a = 1
    
    function fn(a) {
        console.log(a) //undefined
        a = 2 	// 修改的是形参
        console.log(a) // 2
    }
    
    fn()
    console.log(a) // 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    练习4

    var a = 1
    
    function fn(a) {
        console.log(a) //10
        a = 2
        console.log(a) // 2
    }
    
    fn(10)
    console.log(a) // 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    练习5

    var a = 1
    
    function fn(a) {
        console.log(a) //1
        a = 2
        console.log(a) // 2
    }
    
    fn(a)
    console.log(a) // 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    练习6

    console.log(a)  // a指向的是第五行的函数,var只是声明,并不赋值,如果声明过不会重复赋值
    
    var a = 1
    console.log(a) // 1
    function a() {
        alert(2)
    }
    console.log(a) // 1
    var a = 3
    console.log(a) // 3
    var a = function () {
        alert(4)
    }
    console.log(a) // 打印11行函数
    var a	// 已经声明过了,根本不执行
    console.log(a) // 打印11行函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    CentOS 30分钟部署免费在线客服系统
    高并发下秒杀商品,你必须知道的9个细节
    FPGA_Vivado软件初次使用流程_超详细
    数据库内核面试中我不会的问题(2)
    基于MIPI的高性能成像系统
    代码随想录算法训练营Day32 | 贪心算法(2/6) Leetcode 122.买卖股票的最佳时机 II 55. 跳跃游戏 45.跳跃游戏II
    5--Linux:文件
    [go学习笔记.第十三章.单元测试] 1.单元测试
    算法竞赛入门【码蹄集新手村600题】(MT1451-1500)
    Drools规则属性,高级语法
  • 原文地址:https://blog.csdn.net/qq_46311811/article/details/128137468