首页  >  问答  >  正文

JavaScript中变量的作用域是什么?

<p>JavaScript中变量的作用域是什么?它们在函数内部和外部的作用域是否相同?或者这是否重要?此外,如果变量是全局定义的,它们存储在哪里?</p>
P粉696891871P粉696891871398 天前495

全部回复(2)我来回复

  • P粉546257913

    P粉5462579132023-08-22 12:41:43

    Javascript使用作用域链来确定给定函数的作用域。通常有一个全局作用域,每个定义的函数都有自己的嵌套作用域。在另一个函数内定义的任何函数都有一个与外部函数链接的局部作用域。它始终是源代码中的位置定义作用域。

    作用域链中的元素基本上是一个带有指向其父作用域的指针的映射。

    在解析变量时,javascript从最内层作用域开始向外搜索。

    回复
    0
  • P粉165522886

    P粉1655228862023-08-22 10:58:25

    TLDR

    JavaScript具有词法(也称为静态)作用域和闭包。这意味着你可以通过查看源代码来确定标识符的作用域。

    四种作用域如下:

    1. 全局 - 对所有内容可见
    2. 函数 - 在函数内部可见(以及其子函数和块内部)
    3. 块 - 在块内部可见(以及其子块内部)
    4. 模块 - 在模块内部可见

    除了全局和模块作用域的特殊情况外,变量使用var(函数作用域)、let(块作用域)和const(块作用域)声明。在严格模式下,大多数其他形式的标识符声明都具有块作用域。

    概述

    作用域是代码库中标识符有效的区域。

    词法环境是标识符名称与与之关联的值之间的映射。

    作用域由词法环境的链接嵌套形成,每个嵌套级别对应于祖先执行上下文的词法环境。

    这些链接的词法环境形成了作用域“链”。标识符解析是沿着此链搜索匹配标识符的过程。

    标识符解析只会向外进行。这样,外部词法环境无法“看到”内部词法环境。

    在决定JavaScript中标识符的作用域时,有三个相关因素:

    1. 标识符的声明方式
    2. 标识符的声明位置
    3. 是否处于严格模式非严格模式

    一些标识符的声明方式:

    1. varletconst
    2. 函数参数
    3. catch块参数
    4. 函数声明
    5. 命名函数表达式
    6. 全局对象上的隐式定义属性(即,在非严格模式下省略var
    7. import语句
    8. eval

    一些标识符的声明位置:

    1. 全局上下文
    2. 函数体
    3. 普通块
    4. 控制结构的顶部(例如,循环,if,while等)
    5. 控制结构体
    6. 模块

    声明样式

    var

    使用var声明的标识符具有函数作用域,除非它们直接在全局上下文中声明,此时它们将作为全局对象的属性添加,并具有全局作用域。它们在eval函数中的使用有单独的规则。

    let和const

    使用letconst声明的标识符具有块作用域,除非它们直接在全局上下文中声明,此时它们具有全局作用域。

    注意:letconstvar都被提升。这意味着它们的逻辑定义位置是其封闭作用域(块或函数)的顶部。但是,使用letconst声明的变量在控制流程通过源代码的声明点之前不能被读取或赋值。这个临时期被称为暂时死区。

    function f() {
        function g() {
            console.log(x)
        }
        let x = 1
        g()
    }
    f() // 1 because x is hoisted even though declared with `let`!

    回复
    0
  • 取消回复