Javascript 简明教程

JavaScript - Variable Scope

JavaScript Variable Scope

JavaScript 中的 {s0} 决定了变量在代码不同部分的可访问性和可见性。{s1} 是代码执行的当前上下文。这意味着变量作用域是由其执行的位置而不是声明的位置决定的。

在 JavaScript 中,对象和函数也是变量。所以 JavaScript 变量 {s2} 也决定了程序中对象和函数的可访问性或可见性。

了解 JavaScript 中的变量作用域对于编写清晰的代码和避免命名冲突至关重要。

JavaScript 中有以下几种类型的变量作用域。

  1. Block scope

  2. Function scope

  3. Local scope

  4. Global scope

在此,我们将介绍块、函数和局部作用域。我们在 JavaScript 全局变量章节中详细讨论了全局作用域。

JavaScript Block Scope

在 JavaScript ES6 之前,只有全局和函数作用域。ES6 引入了 let 和 const 关键字。这些关键字提供 JavaScript 中的块作用域。

使用 { } 块内的 'let' 和 'const' 关键字定义的 JavaScript 变量只能在其定义的块内进行访问。

{
   let x = 10; // x is accessible here
}
//x is not accessible here

使用 var 关键字定义的变量不会提供块作用域。

{
   var x = 10; // x is accessible here
}
//x is accessible here also

Example

在下面的示例中,我们在 'if' 块内定义了变量 'a'。在输出中,你可以看到变量 'a' 只能在 'if' 块内访问。如果你尝试在 'if' 块之外访问变量 'a',它将抛出引用错误,如“变量 a 未定义”。

<html>
<head>
   <title> JavaScript - Block scope </title>
</head>
<body>
   <p id = "output"> </p>
   <script>
      if (true) {
         let a = 10;
         document.getElementById("output").innerHTML = "a = " + a;
      }
      // a can't be accessed here
   </script>
</body>
</html>
a = 10

Example

在下面的代码中,我们定义了 test() 函数。在函数中,我们使用花括号添加了一个 { } 块,在 { } 块内,我们定义了变量 'x'。变量 'x' 不能在 { } 块外部访问,因为它有块作用域。

<html>
<head>
   <title> JavaScript - Block scope </title>
</head>
<body>
   <p id = "demo"> </p>
   <script>
      const output = document.getElementById("demo");
      function test() {
         {
            let x = 30;
            output.innerHTML = "x = " + x;
         }
         // variable x is not accessible here
      }
      test();
   </script>
</body>
</html>
x = 30

每当你使用块内的 'let' 或 'const' 关键字定义变量时,比如循环块、if-else 块等,都无法在块外部访问该变量。

JavaScript Function Scope

在 JavaScript 中,每个函数创建一个作用域。在函数内定义的变量具有函数作用域。在函数中定义的变量只能从同一函数中访问。这些变量不能从函数外部访问。

每当你使用 'var' 关键字在函数中定义变量时,都可以访问该变量,即使该变量是在特定块内定义的。

例如,

function func() {
   {
      var x; // function scope
      let y; // Block scope
      const z = 20; // Block scope
   }
   // x is accessible here, but not y & z
}

Example

在下例中,我们使用 var、let 和 const 关键字分别定义了变量 'x'、'y' 和 'z'。变量 'x' 可以在整个函数的任何地方访问,因为它具有函数作用域,但 'y' 和 'z' 只能在其定义的块内访问。

<html>
<head>
   <title> JavaScript - Function scope </title>
</head>
<body>
   <p id = "demo"> </p>
   <script>
      const output = document.getElementById("demo");
      function func() {
         {
            var x = 30;
            let y = 20;
            const z = 10;
            output.innerHTML += "x -> Inside the block = " + x + "<br>";
            output.innerHTML += "y -> Inside the block = " + y + "<br>";
            output.innerHTML += "z -> Inside the block = " + z + "<br>";
         }
         output.innerHTML += "x -> Outside the block = " + x + "<br>";
         // y and z can't be accessible here
      }

      func();
   </script>
</body>
</html>
x -> Inside the block = 30
y -> Inside the block = 20
z -> Inside the block = 10
x -> Outside the block = 30

JavaScript Local Scope

JavaScript 局部作用域是函数和块作用域的组合。当函数被调用时,JavaScript 编译器创建局部变量,当函数调用完成时将其删除。

简而言之,在函数或块内定义的变量是该特定作用域的局部变量。函数参数在函数内被视为局部变量。

Example

在下面的代码中,我们使用 var、let 和 const 关键字在函数内定义了变量。所有变量都是函数的局部变量。无法在函数外部访问它。

同样,我们可以在局部作用域中定义循环变量。

<html>
<head>
   <title> JavaScript - Local scope </title>
</head>
<body>
   <p id = "demo"> </p>
   <script>
      const output = document.getElementById("demo");
      function func() {
         let first = 34;
         var second = 45;
         const third = 60;

         output.innerHTML += "First -> " + first + "<br>";
         output.innerHTML += "Second -> " + second + "<br>";
         output.innerHTML += "Third -> " + third + "<br>";
      }
      func();
   </script>
</body>
</html>
First -> 34
Second -> 45
Third -> 60

我们注意到,当一个变量在函数内定义时,该变量成为函数的局部变量。在这种情况下,变量具有函数作用域。当一个变量在特定块内定义时,它成为该块的局部变量并具有块作用域。