我们应该手动将所有JavaScript变量提升到函数定义的前面吗?

时间:2017-04-14 17:49:56

标签: javascript hoisting

我听说过,因为JavaScript会将所有局部变量提升到函数的前面,所以如果程序员只是自己提升它就更好了,这样就可以看出事情是如何发生的。

示例是:

var i, result = [];

用于在函数开头声明所有局部变量。

但我也在一些经典代码中看到过,例如在React JS的源代码中它会做什么

for (var i = 0; i < ...; i++) { ... }

即,首次使用i时声明它 - 这样如果删除此行,声明将一起删除。

如果我们手动提升它,那么当移除该循环时,var i;仍然存在。 (虽然linting可能会抓住它)。

当我将所有变量提升到函数定义的前面时,我也看到了面试官的奇怪表情。

我们应该将所有变量提升到前面吗?或者如果我们提升除ij等临时变量之外的所有变量会怎么样?

4 个答案:

答案 0 :(得分:2)

限制变量暴露于它们有用的上下文可能是一个非常有价值的自动文档策略:它让下一个获取代码的人知道变量在哪里和不相关。所以不,不要提升&#34;因为JavaScript引擎在内部执行它

答案 1 :(得分:0)

几年前这可能是相关的。

现在,您应该使用ES5或更高版本,它引入了let关键字,解决了提升问题。 let声明了变量are block-scoped and will not be hoisted

答案 2 :(得分:0)

我猜有时使用严格模式

是有意义的
"use strict";

可以为整个文件或函数实现

function strictFunction() {
   "use strict";
    var y = 3.14;   // This is ok
        x = 2.414; // This will cause error
}

可以通过避免全局变量来帮助编写更安全的代码。从技术上讲,这取决于你的 for loop 的使用方式。参考"use strict";

您也可以使用@ let代替var或@ int i; if(...) { i=1; } else if(...) { i=2; } 来建立@RemcoGerlich以确定变量范围

答案 3 :(得分:0)

  

当我将所有变量提升到函数定义的前面时,我也看到了面试官的奇怪表情。

     

我们应该将所有变量提升到前面吗?或者如果我们提升除了临时变量之外的所有变量,例如i和j?

基本上有两种思想流派。一种是将所有变量声明在一个地方,通常位于其作用域的顶部(如果您使用var关键字,则定义它们的函数)。另一种思想是尽可能地将变量声明到它们的使用位置。他们都有有效的论据,老实说是一个观点和偏好的问题。

在进入let和ES6之前,我先谈谈上面的两个论点。

在范围顶部声明

这样做的好处是,您始终知道变量声明的位置,并始终了解父作用域。在查看函数时,您可以立即确定所使用的变量,并且可以从那里跟踪它们的使用位置。

这样做的缺点在于,根据您的代码结构,它可能是声明变量的位置和使用位置的100行,这有时会使调试成为一个挑战,需要您仔细跟踪您在函数中使用的变量 think ,因为它可能并不总是在顶部声明的变量,尤其是在shadowing的情况下。

声明尽可能靠近变量的使用位置

这样做的好处是,在尝试确定变量作用域和阴影时,很容易确定您正在使用的变量的版本(特别是对于嵌套函数)。另一个优点是代码清理。如果你删除一个函数或一个循环,并且在它上方有一个变量声明,那么删除该变量声明通常也是一个很好的提醒,因为它不再需要了。显然情况并非如此,但很多时候都是如此。当在顶部声明时,变量可能会在声明的海洋中丢失并且不被使用 - 是的,一个短信可以捕获它,所以它可能是一个没有实际意义的点,但它仍然是一个点。

这种缺点与在顶部声明的优点完全相反。如果您希望查看给定范围中使用的变量名称/标识符,则需要进行挖掘。 CTRL + F是您的朋友,但查看一个位置的列表会更快。

现在怎么样let ??

同样,有两种思想流派:一种是“让是新的变种”,另一种是“让我们在语法上做我们已经做过的风格”

例如,请使用以下代码:

var result;
for (var i = 1; i <= 10; i++) {
   result = 2 * i;
   console.log(result);
}

Vs以上。

for (var i = 1; i <= 10; i++) {
   var result = 2 * i;
   console.log(result);
}

现在,从编译器的角度来看,它们是相同的。然而,第二个版本(风格上)告诉读者代码“结果变量仅在此for循环中使用”,而第一个版本对于读者可能会发生或可能不发生的内容是不明确的{ {1}}变量稍后在代码中。这些是开发人员不言而喻的风格和惯例,以传达代码的意图。这就是第二种思想流派的论证 - result只允许我们在语法上做我们已经在风格上做的事情。