正文
javascript,通常被称为“web 语言”,是一种多功能且广泛使用的编程语言。它以其怪癖而闻名,其中之一就是 hoisting(提升)。无论你是经验丰富的开发人员还是刚刚开始你的编码之旅,理解提升对于编写干净和高效的 javascript 代码至关重要。
在本文中,我们将带您了解 javascript 中的提升概念,揭示变量和函数是如何被提升的。到最后,你不仅能掌握提升背后隐藏的机制,还能学会如何利用它为你带来优势。话不多说,让我们一起进入 javascript 提升的迷人世界!
什么是提升?
在我们深入研究细节之前,让我们揭开 javascript 中提升的神秘面纱。提升是一个后台进程,它在编译阶段将变量和函数声明移动到它们所包含作用域的顶部。这允许你在正式声明它们之前就使用它们。
想象一下,它就像一个魔术师从帽子里拿出一只兔子,兔子就是你的变量或函数,帽子就是 javascript 引擎,提升确保魔术师(javascript)总是能找到它需要的兔子(变量或函数),无论它被放在代码的什么位置。
变量提升
var 的魔力
在 javascript 中,用 var
声明的变量会表现出一种奇怪的提升行为,当你用 var
声明一个变量时,它会被提升到它所属的函数或全局作用域的顶部。考虑以下例子:
function hoistexample() { console.log(myvar); // outputs: undefined var myvar = 42; console.log(myvar); // outputs: 42 } hoistexample();
在 hoistexample
函数中,我们尝试在声明 myvar
之前记录它的值。令人惊讶的是,第一个 console.log
语句没有抛出错误。相反,它输出了 undefined
。这是由于提升 —— myvar
的声明被移动到函数的顶部,使其在整个作用域中可访问。
let 和 const 的混合
var
的行为似乎有悖直觉,而且它经常导致意外的 bug,为了解决这个问题,javascript 引入了 let
和 const
,它们具有不同的提升机制。
function hoistexample() { console.log(myvar); // throws a referenceerror let myvar = 42; console.log(myvar); } hoistexample();
使用 let
和 const
时,仍然会发生提升,但是变量在代码中实际声明之前不会初始化。这意味着在声明 myvar
之前尝试访问它会导致 referenceerror
。这种行为促进了代码的更清晰和更可预测性。
函数声明 vs. 表达式
函数声明提升
就像变量一样,javascript 中的函数也会被提升,让我们来探讨一下在提升时函数声明和函数表达式之间的区别。
hoistme(); // outputs: "i'm hoisted!" function hoistme() { console.log("i'm hoisted!"); }
在这个例子中,我们在声明 hoistme
函数之前调用它。由于提升,没有错误,函数按预期执行。函数声明被整体提升,使它们在作用域内的任何地方可用。
函数表达式
另一方面,函数表达式有不同的提升行为。
hoistme(); // throws a typeerror var hoistme = function () { console.log("i'm not hoisted!"); };
在这种情况下,当我们试图在 hoistme
的声明之前调用它时,我们遇到了一个 typeerror
。函数表达式不会以与函数声明相同的方式被提升。变量 hoistme
被提升了,但它对函数的赋值没有,这就是为什么在赋值之前调用它会导致错误。
作用域和提升
要完全理解提升,必须掌握 javascript 中的作用域的概念,作用域决定了变量和函数在代码中的访问位置。
全局作用域
在任何函数或代码块之外声明的变量具有全局作用域,可以在 javascript 代码的任何位置访问它们。
var globalvar = "i'm global!"; function accessglobalvar() { console.log(globalvar); // outputs: "i'm global!" } accessglobalvar();
在上面的例子中, globalvar
在 accessglobalvar
函数中可用,因为它具有全局作用域。
局部作用域
在函数或代码块中声明的变量具有局部作用域,只能在声明它们的作用域中访问它们。
function localscopeexample() { var localvar = "i'm local!"; console.log(localvar); // outputs: "i'm local!" } localscopeexample(); console.log(localvar); // throws a referenceerror
在 localscopeexample
函数中, localvar
具有局部作用域,因此在函数之外无法访问它。尝试全局访问它会导致 referenceerror
。
常见的提升陷进
理解提升对于编写干净、无 bug 的代码至关重要。以下是处理提升时需要注意的一些常见陷阱:
重定义变量
当你在同一个作用域中使用 var
多次声明同一个变量时,它不会抛出错误,只是简单地重新赋给变量一个新值。
var myvar = "first declaration"; var myvar = "second declaration"; console.log(myvar); // outputs: "second declaration"
这种行为会导致意想不到的后果,因为重定义变量会使代码更难理解和维护。使用 let
和 const
来防止意外的变量重声明。
函数重写
在 javascript 中,如果你多次声明同一个函数,最后一次声明将覆盖之前的任何一次声明,这可能会导致意想不到的行为和错误。
function myfunction() { console.log("first definition"); } function myfunction() { console.log("second definition"); } myfunction(); // outputs: "second definition"
为了避免函数重写,请始终使用唯一的函数名,并保持清晰和有组织的代码结构。
代码整洁的最佳实践
既然我们已经探讨了提升的细微差别和潜在的陷阱,那么让我们深入研究一些最佳实践,以编写干净和可维护的 javascript 代码。
正确声明变量
为了防止与提升相关的问题,在变量的作用域顶部声明变量,如果你使用 var
,考虑切换到 let
或 const
来利用块作用域,这更可预测,更安全。
function cleancodeexample() { var localvar = "i'm declared at the top"; //此处显示您的其余代码 }
通过在开头声明变量,可以使代码更具可读性,并减少遇到意外情况的可能性。
组织函数
当使用函数时,请确保定义一致。在代码库中使用函数声明或函数表达式来维护统一的结构。
// 良好做法 function calculatesum(a, b) { return a + b; } // 避免混淆函数声明和表达式 var multiply = function (a, b) { return a * b; };
代码风格的一致性不仅可以提高代码的清晰度,还可以最大限度地减少与提升相关的问题。
总结:提升的力量
javascript 提升是一种隐藏的魔法,它通过将变量和函数声明移动到其作用域的顶部来优化代码,从而增强语言的行为。了解各种变量声明和函数声明的提升,可以让代码更简洁,让专家更熟练。接受并掌握这种方法可以提高代码编写的效率和优雅程度,使其成为开发人员的重要工具。总之,在编码过程中,javascript 的怪异之处(包括提升)应作为资产加以利用,以提高工作效率和编码技能。
翻译自:https://vishwasacharya.hashnode.dev/hoisting-in-javascript
以上就是javascript 提升hoisting的详细内容,更多关于javascript变量提升hoisting的资料请关注代码网其它相关文章!
发表评论