什麼是 JavaScript 中的變數遮蔽?
在程式設計中,遮蔽是指在某個作用域(例如區域性變數)中宣告的變數與外部作用域(例如全域性變數)中的變數同名的情況。發生這種情況時,外部變數被稱為被內部變數遮蔽。
在 JavaScript 中,變數可以在全域性和函式作用域中被遮蔽。全域性變數可以被函式作用域變數遮蔽,函式作用域變數可以被使用 let 或 const 關鍵字宣告的塊作用域變數遮蔽。
全域性作用域中的變數遮蔽
在全域性作用域中,當使用 var 關鍵字宣告的變數與使用 let 或 const 關鍵字宣告的變數同名時,就會發生遮蔽。發生這種情況時,全域性變數被稱為被函式作用域變數遮蔽。
示例
例如,考慮以下程式碼:
<!doctype html> <html> <body> <div id="result1"></div> <div id="result2"></div> <script> var x = "global"; function foo() { let x = "function"; document.getElementById("result1").innerHTML = x } foo(); document.getElementById("result2").innerHTML = x </script> </body> </html>
在此程式碼中,全域性變數 x 被 foo() 函式內部宣告的函式作用域變數 x 遮蔽。結果,x 的值在 foo() 函式內部和外部是不同的。
函式作用域中的變數遮蔽
在函式作用域中,當使用 let 或 const 關鍵字宣告的變數與使用 var 關鍵字宣告的變數同名時,就會發生遮蔽。發生這種情況時,函式作用域變數被稱為被塊作用域變數遮蔽。
示例
例如,考慮以下程式碼:
<html> <body> <div id="result1"></div> <div id="result2"></div> <div id="result3"></div> <script> function foo() { var x = "function"; document.getElementById("result1").innerHTML = x { let x = "block"; document.getElementById("result2").innerHTML = x } document.getElementById("result3").innerHTML = x } foo(); </script> </body> </html>
在此程式碼中,函式作用域變數 x 被塊內部宣告的塊作用域變數 x 遮蔽。結果,x 的值在塊內部和外部是不同的。
變數遮蔽的優點
示例 1
變數遮蔽可以用來提高程式碼的可讀性和清晰度。例如,考慮以下程式碼:
<html> <body> <div id="result1"></div> <div id="result2"></div> <script> function foo(x) { if (x > 10) { let y = "big"; } else { let y = "small"; } document.getElementById("result1").innerHTML = y } try{ foo(20) } catch(err){ document.getElementById("result2").innerHTML = err } </script> </body> </html>
在此程式碼中,變數 y 在 if 和 else 塊中都被宣告。但是,由於這兩個變數位於不同的塊中,它們不是同一個變數。因此,嘗試訪問其塊外部的 y 變數將導致 ReferenceError。
示例 2
遮蔽還可以用來降低錯誤的可能性。例如,考慮以下程式碼:
<html> <body> <div id="result"></div> <script> function foo(x) { let y = x; // y is shadowed by x y = 101; // reassign y, does not reassign x document.getElementById("result").innerHTML = x } foo(10) </script> </body> </html>
在此程式碼中,變數 y 被變數 x 遮蔽。結果,重新賦值 y 變數不會重新賦值 x 變數。這有助於防止意外錯誤,其中變數的值被無意中重新賦值。
變數遮蔽的缺點
示例 1
有時遮蔽也會使程式碼更難理解。例如,考慮以下程式碼:
<html> <body> <div id="result1"></div> <div id="result2"></div> <script> function foo(x) { let y = x; { let x = 10; // x is shadowed by y y = 20; document.getElementById("result1").innerHTML = x } document.getElementById("result2").innerHTML = x } foo(20); </script> </body> </html>
在此程式碼中,x 和 y 變數的值在塊內被交換了。這可能會讓閱讀程式碼的人感到困惑,因為它並不立即清楚 x 和 y 變數已被交換。
示例 2
遮蔽還會使程式碼更難除錯。例如,考慮以下程式碼:
<html> <body> <div id="result1"></div> <div id="result2"></div> <div id="result3"></div> <script> function foo(x) { let y = x; document.getElementById("result1").innerHTML = y { let x = 20; let y = 30; document.getElementById("result2").innerHTML = x } document.getElementById("result3").innerHTML = x } foo(10) </script> </body> </html>
在此程式碼中,並不立即清楚 y 變數的值在塊內已被重新賦值。這可能會使除錯由此重新賦值造成的錯誤變得困難。
遮蔽可以作為一種提高程式碼可讀性和降低錯誤可能性的有用工具。但是,它也可能使程式碼更難理解和除錯。使用遮蔽時,務必考慮其好處是否大於缺點。
資料結構
網路
關係資料庫管理系統 (RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C 程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP