• javascript基础七:说说你对Javascript中作用域的理解?


    在这里插入图片描述
    一、作用域
    作用域,即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合
    换句话说,作用域决定了代码区块中变量和其他资源的可见性

    举个粟子

    function myFunction(){
        let name='小爱同学'
    }
    undefined
    myFunction()
    undefined
    name
    Uncaught ReferenceError: inVariable is not defined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    上述例子中,函数myFunction内部创建一个name变量,当我们在全局访问这个变量的时候,系统会报错
    这就说明我们在全局是无法获取到(闭包除外)函数内部的变量

    我们一般将作用域分成:

    • 全局作用域
    • 函数作用域
    • 块级作用域

    全局作用域

    任何不在函数中或是大括号中声明的变量,都是在全局作用域下,全局作用域下声明的变量可以在程序的任意位置访问

    var globalName = 'hello world'
    undefined
    function getName(){
        console.log(globalName)
    }
    undefined
    getName()
    undefined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ![在这里插入图片描述](https://img-blog.csdnimg.cn/d5b29b175ecc4ed6a3d1c29c9046da3b.png
    函数作用域
    函数作用域也叫局部作用域,如果一个变量是在函数内部声明的它就在一个函数作用域下面。这些变量只能在函数内部访问,不能在函数以外去访问

    function greet() {
      var greeting = 'Hello World!';
      console.log(greeting);
    }
    // 打印 'Hello World!'
    greet();
    // 报错:Uncaught ReferenceError: greeting is not defined
    console.log(greeting);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    可见上述代码中在函数内部声明的变量或函数,在函数外部是无法访问的,这说明在函数内部定义的变量或者方法只是函数作用域

    块级作用域

    ES6引入了let和const关键字,和var关键字不同,在大括号中使用let和const声明的变量存在于块级作用域中。在大括号之外不能访问这些变量

    {
      // 块级作用域中的变量
      let greeting = 'Hello World!';
      var lang = 'English';
      console.log(greeting); // Prints 'Hello World!'
    }
    // 变量 'English'
    console.log(lang);
    // 报错:Uncaught ReferenceError: greeting is not defined
    console.log(greeting);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    二、词法作用域
    词法作用域,又叫静态作用域,变量被创建时就确定好了,而非执行阶段确定的。也就是说我们写好代码时它的作用域就确定了,JavaScript 遵循的就是词法作用域

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

    在这里插入图片描述
    由于JavaScript遵循词法作用域,相同层级的 foo 和 bar 就没有办法访问到彼此块作用域中的变量,所以输出2

    三、作用域链

    当在Javascript中使用一个变量的时候,首先Javascript引擎会尝试在当前作用域下去寻找该变量,如果没找到,再到它的上层作用域寻找,以此类推直到找到该变量或是已经到了全局作用域

    如果在全局作用域里仍然找不到该变量,它就会在全局范围内隐式声明该变量(非严格模式下)或是直接报错

    这里拿《你不知道的Javascript(上)》中的一张图解释:

    把作用域比喻成一个建筑,这份建筑代表程序中的嵌套作用域链,第一层代表当前的执行作用域,顶层代表全局作用域

    在这里插入图片描述
    变量的引用会顺着当前楼层进行查找,如果找不到,则会往上一层找,一旦到达顶层,查找的过程都会停止

    举个粟子

    
    var sex = '男';
    function person() {
        var name = '张三';
        function student() {
            var age = 18;
            console.log(name); // 张三
            console.log(sex); // 男 
        }
        student();
        console.log(age); // Uncaught ReferenceError: age is not defined
    }
    person();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    上述代码主要主要做了以下工作:

    • student函数内部属于最内层作用域,找不到name,向上一层作用域person函数内部找,找到了输出“张三”
    • student内部输出cat时找不到,向上一层作用域person函数找,还找不到继续向上一层找,即全局作用域,找到了输出“男”
    • 在person函数内部输出age时找不到,向上一层作用域找,即全局作用域,还是找不到则报错
  • 相关阅读:
    Python 编程基础 | 第四章-函数 | 4.1、函数定义
    如何使用Flask开发RESTful API
    关于Vuex的基础使用存值及异步
    数据库理论(课件)
    css-水滴登录页
    前端学习案例-重写foreach
    (七)Mybatis传值中#{}和${}的区别,及别名机制
    面试官:说说微服务灰度发布的底层实现?
    消息推送平台有没有保证数据不丢?
    Java_断点调试/类变量/类方法/main语法
  • 原文地址:https://blog.csdn.net/qq_34595425/article/details/130904389