Skip to content

JavaScript Variable Scopes #58

@wangjing013

Description

@wangjing013

概述: 在这篇文章中, 将学习JavaScript 中的作用域, 它决定变量的可见性和可访问性.

什么变量的作用域

作用域决定变量的可见性和可访问性. JavaScript 包含三个作用域: 全局作用域、函数作用域(local)、块级作用域.

全局作用域

当执行一段代码时, JavaScirpt engine 会创建一个全局的执行上下文.

通常在最外层声明的变量会被添加到全局执行上下文中. 这些变量在全局作用域中.

看下面的示例:

var message = 'Hi';

变量 message 是在全局作用域中. 它可以在脚本中的任何地方访问.

JavaScript-Global-Variables

Local scope

您在函数内声明的变量是该函数的局部变量. 它们被称为局部变量. 例如:

var message = 'Hi';

function say() {
    var message = 'Hello';
    console.log('message');
}

say();
console.log(message);

输出:

Hello
Hi

JavaScript engine 执行 say() 函数时, 它将为函数创建一个执行上下文. 在 say() 函数内部声明的变量 message 绑定到 say() 函数对应的执行上下文. 并不是在全局执行上下文中.

JavaScript-Local-Variables

Scope chain

考虑如下示例:

var message = 'Hi';

function say() {
    console.log(message);
}

say();

输出:

Hi

在当前示例中, 在 say() 函数内部中引用变量 message. 在背后,JavaScript 执行以下操作:

  • 从当前 say() 函数上下文中去查找(函数执行上下文). 没有找到
  • 从外部的上下文(全局执行上下文)中查找

JavaScript 通过在其当前作用域中查找变量,如果找不到该变量,则它会上升到外部作用域,称为作用域链.

JavaScript-Scope-Chain

Block scope

ES6 提供 letconst 关键字允许声明块级作用域变量.

看如下示例:

function say(message) {
    if(!message) {
        let greeting = 'Hello';  // block scope
        console.log(greeting);
    }
    console.log(greeting); // ReferenceError
}

say();

在当前示例中, 错误原因是在 if 语句块外面引用变量 greeting.

总结

  • 常见作用域包括: 全局作用域、函数作用域(local)、块级作用域.
  • 作用域链: 从当前作用域中查找,没有查找到则会去外部的作用域中查找,这种行为称为作用域链.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions