返回

揭开 JavaScript 作用域的神秘面纱:深入理解变量的“活动范围”

前端

JavaScript 作用域概述

作用域指的是一个变量被定义的区域范围,它决定了该变量可被使用的范围,以及当前代码访问该变量的权限。在 JavaScript 中,作用域主要分为全局作用域、函数作用域和块级作用域。

  • 全局作用域: 全局作用域是整个 JavaScript 程序中最大范围的作用域,它包含所有在脚本的最外层定义的变量和函数。全局作用域中的变量和函数可以在程序的任何地方访问。
  • 函数作用域: 函数作用域是指由一个函数所定义的作用域,它包含该函数中定义的所有变量和函数。函数作用域中的变量和函数只能在该函数内部访问,不能在其他函数或全局作用域中访问。
  • 块级作用域: 块级作用域是 JavaScript ES6 中引入的新概念,它是指由一对大括号 {} 所定义的作用域,它包含该块级作用域中定义的所有变量和函数。块级作用域中的变量和函数只能在该块级作用域内部访问,不能在其他块级作用域或全局作用域中访问。

闭包

闭包是指一个拥有对另一个函数作用域内的变量的引用并能够在这个函数作用域外部访问这个变量的函数。换句话说,闭包可以让一个函数访问另一个函数作用域内的变量,即使这个函数已经执行完毕。

闭包在 JavaScript 中非常有用,它可以用来实现许多高级的功能,例如私有变量、事件处理程序和模块化编程。

词法作用域

词法作用域是指一个变量的作用域由它在源代码中的位置决定。在 JavaScript 中,词法作用域是由函数和块级作用域决定的。

例如,以下代码中,变量 x 在函数 foo() 中定义,因此它的作用域仅限于函数 foo() 内部:

function foo() {
  var x = 10;
}

console.log(x); // 报错:x 未定义

然而,如果我们将变量 x 定义在函数 foo() 的外层,那么它的作用域将是全局作用域,可以在程序的任何地方访问:

var x = 10;

function foo() {
  console.log(x); // 10
}

console.log(x); // 10

块级作用域

块级作用域是 JavaScript ES6 中引入的新概念,它是指由一对大括号 {} 所定义的作用域,它包含该块级作用域中定义的所有变量和函数。块级作用域中的变量和函数只能在该块级作用域内部访问,不能在其他块级作用域或全局作用域中访问。

例如,以下代码中,变量 x 在块级作用域 {} 中定义,因此它的作用域仅限于该块级作用域内部:

{
  var x = 10;
}

console.log(x); // 报错:x 未定义

全局作用域

全局作用域是整个 JavaScript 程序中最大范围的作用域,它包含所有在脚本的最外层定义的变量和函数。全局作用域中的变量和函数可以在程序的任何地方访问。

例如,以下代码中,变量 x 在全局作用域中定义,因此可以在程序的任何地方访问:

var x = 10;

function foo() {
  console.log(x); // 10
}

console.log(x); // 10

this

this 是指向当前执行代码的对象的引用。this 关键字的值取决于函数的执行环境。

例如,以下代码中,this 关键字指向 window 对象:

function foo() {
  console.log(this); // window
}

foo();

然而,如果我们将函数 foo() 作为另一个对象的方法来调用,那么 this 关键字将指向该对象:

var obj = {
  foo: function() {
    console.log(this); // obj
  }
};

obj.foo();

总结

作用域是 JavaScript 中一个非常重要的概念,它决定了变量和函数的作用范围。在 JavaScript 中,作用域主要分为全局作用域、函数作用域、块级作用域和闭包。

闭包可以让一个函数访问另一个函数作用域内的变量,即使这个函数已经执行完毕。

词法作用域是指一个变量的作用域由它在源代码中的位置决定。

块级作用域是 JavaScript ES6 中引入的新概念,它是指由一对大括号 {} 所定义的作用域。

全局作用域是整个 JavaScript 程序中最大范围的作用域,它包含所有在脚本的最外层定义的变量和函数。

this 关键字是指向当前执行代码的对象的引用。