我可以在声明 JavaScript 变量之前使用它吗?
是的,您可以使用一种称为提升的技术在声明 JavaScript 变量之前使用它。解析器会在运行函数之前读取整个函数。
变量在声明之前似乎被使用的行为称为提升。
例如,以下代码:
rank = 5; var rank;
上面的代码与以下代码作用相同:
var rank; rank = 2;
JavaScript 中的提升允许我们声明变量、函数或类,这些变量、函数或类会在代码执行之前被移动到作用域的顶部,无论它们的作用域是局部还是全局。
JavaScript 在执行之前为所有变量和函数分配内存。请注意,提升指的是声明,而不是初始化。
由于变量和函数在代码中声明之前就被使用,因此可能会出现意外错误。因此,不建议使用提升。提升对 var、let 和 const 的作用不同。我们可以详细检查以下内容。
首先,我们将检查使用 var 进行提升的示例。稍后我们将详细检查变量提升。
示例
<!DOCTYPE html> <html> <body> <h4>Hoisting Example</h4> <p id="output"></p> <script> x = 10; // Assign 5 to x document.getElementById("output").innerHTML = x; var x; // Declare x </script> </body> </html>
在这里,我们可以看到我们在声明 x 变量之前使用了它。
现在,我们将检查 JavaScript 只提升声明,而不提升初始化。让我们看另一个例子
示例
<!DOCTYPE html> <html> <body> <h3>Hoists only declarations</h3> <p id="output"></p> <script> x = 10; // initialize x document.getElementById("output").innerHTML = x + " , " + y; var x; // declare x var y = 20; // declare and initialize y </script> </body> </html>
在这里,我们可以检查提升意味着需要在使用 y 之前对其进行初始化。但是 y 没有初始化。因此,这没有被提升。这就是为什么 y 的值为 undefined。我们可以按照示例 1 中提到的方法正确编写。
示例
<!DOCTYPE html> <html> <body> <h1>Hoists only declarations</h1> <p id="output"></p> <script> var x = 10; // Initialize x var y; // declare y document.getElementById("output").innerHTML = x + " , " + y; y = 20; // Initialize y </script> </body> </html>
在这里,变量 y 已声明,但我们显示它之前未初始化。
JavaScript 只提升声明,不提升初始化。
始终注意,在后台,JavaScript 首先声明变量并为其初始化值。在 JS 中,未声明的变量在分配代码执行之前不存在。因此,在执行赋值代码时,未声明的变量被视为全局变量。让我们更深入地研究变量提升。
let 和 const 提升
我们都知道 let 和 const 是块作用域的,而不是函数作用域的。let 和 const 是在 ES6 中引入的。我们知道 ES6 不允许未声明的值。如果我们尝试在声明之前使用变量,它将抛出引用错误。与 var 不同,变量不会使用默认值初始化。让我们看一个例子
示例
<!DOCTYPE html> <html> <body> <h3>Hoisting with let</h3> <p id="output"></p> <script> try{ document.getElementById("output").innerHTML = x; let x = "Hi"; } catch(err) { document.getElementById("output").innerHTML = err; } </script> </body> </html>
在这里,我们可以观察到我们正在尝试在声明 x 值之前访问它。让我们再看一个关于 let 的例子。
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with let</h2> <p id="result1"></p> <p id="result2"></p> <script> let x; document.getElementById("result1").innerHTML = x; x = 5; document.getElementById("result2").innerHTML = x; </script> </body> </html>
现在,让我们检查 const。
使用 const 进行提升
与 let 一样,我们不能在声明之前使用变量,而且我们不仅需要声明变量,还需要为其初始化值。否则,它将抛出 SyntaxError 错误。让我们看一个例子
示例
<!DOCTYPE html> <html> <body> <h1>Hoisting with const</h1> <p> It will throw Uncaought SyntaxError: Missing initializer in const declaration </p> <p> To see this error please open the Console of the browser </p> <p id="output"></p> <script> const x; document.getElementById("output").innerHTML = x; x = 5; document.write(x); </script> </body> </html>
声明时需要初始化值。
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with const</h2> <p id="output"></p> <script> try{ document.getElementById("output").innerHTML = x; const x = 5; }catch(err){ document.getElementById("output").innerHTML = err; } </script> </body> </html>
与上述示例一样,const 也无法实现。它将抛出引用错误。
现在,让我们看看函数的提升。
函数提升
函数提升允许我们在定义函数之前调用它。让我们看一个例子
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with function</h2> <p id="output"></p> <script> getName("Devika"); function getName(name) { document.getElementById("output").innerHTML = ("Employee name is " + name); } </script> </body> </html>
如果将函数表达式赋值给变量。输出将取决于变量范围。像这样:
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with function as var</h2> <p id="output"></p> <script> try{ getName("Devika"); var getName = function (name) { document.getElementById("output").innerHTML = ("Employee name is " + name); } }catch(err){ document.getElementById("output").innerHTML = err; } </script> </body> </html>
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with function as let</h2> <p id="output"></p> <script> try{ getName("Devika"); let getName = function (name) { document.getElementById("output").innerHTML = ("Employee name is " + name); } }catch(err){ document.getElementById("output").innerHTML = err; } </script> </body> </html>
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with function as const</h2> <p id="output"></p> <script> try{ getName("Devika"); const getName = function (name) { document.getElementById("output").innerHTML = ("Employee name is " + name); } }catch(err){ document.getElementById("output").innerHTML = err; } </script> </body> </html>
在这里我们可以观察到,带有变量的函数的工作方式不同。如果我们将函数表达式赋值为 var,我们将得到 TypeError,而使用 let 和 const,我们将得到 ReferenceError。
但是,在声明之前使用函数是我们的个人喜好问题。
希望本教程能让你了解 js 中的提升以及提升如何与变量和函数一起工作。