什么是 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 变量的值在块内已被重新赋值。这可能会使调试由此重新赋值造成的错误变得困难。

遮蔽可以作为一种提高代码可读性和降低错误可能性的有用工具。但是,它也可能使代码更难理解和调试。使用遮蔽时,务必考虑其好处是否大于缺点。

更新于:2022年8月3日

5K+ 次浏览

启动你的职业生涯

通过完成课程获得认证

开始学习
广告
© . All rights reserved.