Scope 是 JavaScript 和编程的一个重要方面. Scope 限制了整个代码中变量, 函数和对象的可见性以及可用性.
这带来了很多好处, 其中包括:
安全 - 变量只能在需要的地方访问.
减少变量名空间冲突 - 当两个或更多变量共享一个通用名称时, 会发生变量名冲突. 变量范围有助于减少阻止这种情况发生.
在最基本的层面上, JavaScript 有两种类型的范围:
- Global Scope(全局作用域)
- Local Scope(局部作用域)
全局作用域
当你开始用 JavaScript 编写代码时, 你就已经在全局范围内. 任何在全局范围内编写的东西都可以在 JavaScript 代码中的任何地方访问
- var cat = 'Jerry';
- function localScopeExample(){
- // LOCAL SCOPE
- console.log(cat); // Jerry
- }
- // GLOBAL SCOPE
- console.log(cat); // Jerry
局部作用域
局部作用域稍微复杂一点. 局部作用域变量只能在局部作用域 (它们被定义的地方) 中可见和可访问. 您可以将局部作用域视为您在全局范围内创建的任何新范围.
一个简单的例子就是在使用函数时. 用 JavaScript 编写的每个函数都会创建一个新的局部作用域. 这些局部作用域的变量只能在它们定义的函数中访问.
我们来看一个例子. 我们将创建一个函数并在该函数中声明变量 cat. 猫可以访问并且可以在该功能的任何地方使用. 但是, 在函数之外调用 cat 将导致 Uncaught ReferenceError:
- function localScopeExample(){
- // LOCAL SCOPE
- var cat = 'Jerry';
- console.log(cat); // Jerry
- }
- // GLOBAL SCOPE
- console.log(cat); // Uncaught ReferenceError: cat is not defined
由于局部变量只能在其函数中访问, 因此可以在不同的函数中使用相同的变量名称:
- function func1(){
- var cat = 'Jerry';
- console.log(cat); // Jerry
- }
- function func2(){
- var cat = 'Tom';
- console.log(cat); // Tom
- }
词法作用域
学习词法作用域也很重要. 词法作用域 (也称为静态作用域) 是内部函数访问外部函数范围的能力.
我们来看一个例子. 在下面的代码中, 我们定义了两个函数 - func1 在全局范围内, func2 在 func1 范围内声明. 由于词汇范围的限制, 您可以在范围 2 中访问全局作用域和范围 1 中的所有内容:
- // GLOBAL SCOPE
- var dog = 'Lewis';
- function func1(){
- // SCOPE 1
- var cat = 'Jerry';
- var func2 = function(){
- // SCOPE 2
- console.log(cat); // Jerry
- console.log(dog); // Lewis
- }
- }
块级作用域
使用 var 时, 变量既可以是全局作用域, 也可以局部作用于定义它的函数. 块级作用域如 if,for,while,{}对 var 没有影响.
let & const, 另一方面, 它们被限定在它们所定义的区块内. 我们来看一个例子:
- let x = 1;
- {
- let x = 2;
- console.log(x); // 2
- }
- console.log(x); // 1
正如你在上面看到的那样, 简单地使用括号来创建一个代码块将在本地范围内在该块内声明的任何变量. 相同的概念适用于其他块范围:
- let x = 1;
- if (x !== 2) {
- let x = 2;
- console.log(x); // 2
- }
- console.log(x); // 1
但要小心. 如果您不小心重新声明具有相同块范围的相同变量, 则会出现错误:
- {
- let x = 1;
- let x = 2;
- }
Uncaught SyntaxError: Identifier 'x' has already been declared
关键要点:
全局范围的持续时间与系统一样长.
局部变量在函数启动时创建, 并在函数结束时删除.
词法作用域允许内部函数访问其外部函数的作用域
const 和 let 是块范围变量. 块范围不适用于 var.
来源: https://juejin.im/entry/5af56ce3f265da0b736db5d8