• 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
  • 相关阅读:
    传输大文件小工具:bypy
    代码随想录 | Day 58 - LeetCode 739. 每日温度、496. 下一个更大元素 I
    1587 - Box (UVA)
    Mysql的函数方法
    MBps与Mbps区别
    【axios】的浅度分析
    Perforce 使用建议
    C++初阶 类和对象(下)
    OPUS解码器PLC
    MindSpore数据集加载-GeneratorDataset功能及常见问题
  • 原文地址:https://blog.csdn.net/qq_46311811/article/details/128137468