解釋 JavaScript 中的作用域和作用域鏈


在 JavaScript 中,作用域定義了我們如何在程式碼的哪個部分訪問變數和函式。簡單來說,作用域有助於提高程式碼的安全性和可讀性。因此,我們只能在其作用域內訪問變數和函式,而不能在外部訪問。

本教程將討論多種型別的作用域。

JavaScript 中的全域性作用域

全域性定義的變數和函式(在所有塊和函式之外)具有全域性作用域。我們可以在程式碼的任何地方訪問具有全域性作用域的所有變數和函式。

語法

使用者可以按照以下語法定義具有全域性作用域的變數。

var global = 30;
function func() {
   var b = global; // global variable has a global scope so we can access it inside the function.
}

這裡,全域性變數global是在任何函式之外宣告的,因此它具有全域性作用域。然後,透過宣告區域性變數 b 並將其賦值為全域性變數global的值,在函式func內部訪問它。

示例

在這個例子中,我們用全域性作用域定義了全域性變數。我們在名為func()的函式內訪問它,並從函式中返回它的值。

在輸出中,我們可以觀察到 func() 函式返回 20,這是全域性變數的值。

<html>
   <body>
      <h2> Defining a variable with <i> global </i> scope </h2>
      <div id = "output"> </div>
      <script>
         let output = document.getElementById("output");
         var global = 20;
         function func() {
            return global;
         }
         output.innerHTML += "The value of variable named global: " + func();
      </script>
   </body>
</html>

區域性/函式作用域

區域性作用域也稱為函式作用域。在函式內部定義的變數具有函式作用域/區域性作用域。我們不能在函式外部訪問這些變數。

語法

您可以按照以下語法來理解變數和函式的區域性作用域:

function func() {
   var local_var = "Hi!";
}
console.log(local_var); // this will raise an error

這裡local_varfunc()函式內具有函式作用域,因此我們不能在函式外部訪問它。

示例

在這個例子中,我們建立了 func() 函式。在 func() 函式內部,我們定義了具有區域性作用域的local_var變數,這意味著我們只能在 func() 函式內部訪問它。我們可以看到,如果我們嘗試在 func() 函式外部訪問local_var,它會丟擲一個local_var未定義的錯誤。要檢視此錯誤,您需要開啟控制檯。

<html>
   <body>
      <h2>Defining a variable with <i> function </i> scope</h2>
      <div id = "output"> </div>
      <script>
         let output = document.getElementById("output");
         function func() {
            let local_var = 20;
            output.innerHTML += "The value of local_var inside fucntion: " + local_var + "<br/>";
         }
         func();
         // the local_var can't be accessed here
         output.innerHTML += "The value of local_var outside fucntion: " +local_var+ "<br/>";
      </script>
   </body>
<html>

塊作用域

在 JavaScript 中,我們可以使用兩個花括號{}來定義。塊作用域表示,我們在特定塊內定義的任何變數只能在該塊內訪問,而不能在該塊外訪問。用letconst關鍵字宣告的變數具有塊作用域。

語法

使用者可以按照以下語法來理解變數的塊作用域。

{
   let block_var = 6707;
   // block_var accessible here
}

// we can't access the block_var variable here.

在這裡,我們不能在花括號外部訪問block_var,因為我們是在特定塊內定義它的。

注意 - 用var關鍵字宣告的變數沒有塊作用域。

示例

在這個例子中,我們使用花括號定義了一個塊,並定義了一個變數num。我們嘗試在塊內和塊外訪問這個變數。您可以觀察到,我們不能在花括號外部訪問num,因為我們是在塊內定義它的。

<html>
   <body>
      <h2>Defining the variable with <i> block </i> scope </h2>
      <div id="output"></div>
      <script>
         let output = document.getElementById("output");
         {
            const num = 200;
            output.innerHTML += "Value of num inside the block: " + num + "<br>";
         }
         // num is accessible here - outside the block
         output.innerHTML += "value of num outside the block: " + num + "<br>";
      </script>
   </body>
</html>

詞法作用域

詞法作用域與靜態作用域相同。在 JavaScript 中,當我們執行巢狀函式並嘗試訪問巢狀函式內的任何變數時,它首先在區域性上下文內查詢變數。如果它沒有在巢狀函式的區域性上下文中找到變數,它會嘗試在從其執行函式的父上下文中查詢,依此類推。最後,如果它沒有在全域性上下文中找到變數,則認為它是未定義的。

語法

使用者可以按照以下語法來理解詞法作用域。

var parent_var = 343;
var test = function () {
   console.log(parent_var);
};
test();

在上面的語法中,我們從執行函式的作用域訪問了parent_var。由於函式log()不會在區域性作用域中找到parent_var,它將嘗試在呼叫函式的作用域(即全域性作用域)中查詢。

示例

在這個例子中,我們定義了 test() 函式和巢狀的 nested() 函式。此外,我們在 nested() 函式內部訪問了 global_var 和 parent_var。由於 JavaScript 不會在區域性上下文中找到這兩個變數,它將首先在 nested() 函式的執行上下文中查詢,然後在 test() 函式的執行上下文中查詢。

<html>
   <body>
      <h2>Defining the variables with <i> lexical </i> scope</h2>
      <div id="output"></div>
      <script>
         let output = document.getElementById("output");
         var global_var = 576505;
         var test = function () {
            var parent_var = 343;
            var nested = function () {
               output.innerHTML += "The value of parent_var: " + parent_var + "<br/>";
               output.innerHTML += "The value of global_var: " + global_var + "<br/>";
            };
            nested();
         };
         test();
      </script>
   </body>
</html>

作用域鏈

正如作用域鏈這個詞所暗示的那樣,它是一條作用域鏈。例如,假設我們在函式內部定義巢狀函式。在這種情況下,它可以有自己的區域性作用域,並且在巢狀函式內宣告的變數不能在外部函式中訪問。

因此,我們正在建立作用域鏈;這就是我們稱之為作用域鏈的原因。

語法

使用者可以按照以下語法學習作用域鏈。

function outer() {
   function inner() {
      // inner’s local scope.
      
      // we can access variables defined inside the outer() function as inner is inside the local scope of outer
   }
   
   // variables defined in the inner() function, can’t be accessible here.
}

示例

在這個例子中,inner() 函式在 outer() 函式的作用域內,這意味著我們不能在 outer() 函式外部呼叫 inner() 函式。inner() 函式在 outer() 函式內建立作用域鏈。

<html>
   <body>
      <h2>Scope Chain in JavaScript </i></h2>
      <div id="output"></div>
      <script>
         let output = document.getElementById("output");
         function outer() {
            var emp_name = "Shubham!";
            function inner() {
               var age = 22;
               output.innerHTML += ("The value of the emp_name is " + emp_name) +"<br/>";
               output.innerHTML += "The value of the age is " + age;
            }
            inner();
            
            // age can't be accessible here as it is the local scope of inner
         }
         outer();
      </script>
   </body>
</html>

在本教程中,我們討論了 JavaScript 中的作用域和作用域鏈。我們討論了全域性、區域性/函式、塊和詞法作用域。在最後一節中,我們瞭解了作用域鏈在 Javascript 中是如何工作的。

更新於:2023年1月5日

1000+ 次瀏覽

啟動你的職業生涯

完成課程獲得認證

開始
廣告
© . All rights reserved.