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

我们是否应该手动将所有JavaScript变量提升到函数定义的前面?,javascript,hoisting,Javascript,Hoisting,我听说,由于JavaScript会将所有局部变量提升到函数的前面,因此程序员最好自己提升它,这样所有事情都会被视为实际发生的方式 例如: var i, result = []; 在函数的开头声明所有的局部变量 但我也在一些经典代码中看到了,比如React JS的源代码 for (var i = 0; i < ...; i++) { ... } for(var i=0;i

我听说,由于JavaScript会将所有局部变量提升到函数的前面,因此程序员最好自己提升它,这样所有事情都会被视为实际发生的方式

例如:

var i, result = [];
在函数的开头声明所有的局部变量

但我也在一些经典代码中看到了,比如React JS的源代码

for (var i = 0; i < ...; i++) { ... }
for(var i=0;i<…;i++){…}
也就是说,在第一次使用
i
时声明它——因此,如果删除这一行,声明将一起删除

如果我们手动提升,则存在一种危险,即当移除该回路时,
var i仍然留在那里。(尽管林廷可能会抓住它)

当我把所有的变量都放在函数定义的前面时,我也从面试官那里看到了奇怪的表情


我们应该把所有变量都放到前面吗?或者,如果我们提升除临时变量(如
i
j
?)之外的所有变量,将变量暴露在有用的上下文中,这可能是一个非常有价值的自动文档策略:它让下一个获取代码的人知道变量在哪里,并且不相关。因此,不,不要“提升”,因为JavaScript引擎在内部执行它

这可能在几年前就已经相关了


现在,您应该使用ES5或更高版本,它引入了
let
关键字,解决了提升问题<代码>让
声明变量。

我想有时候使用严格模式是有意义的

"use strict";
可以为整个文件或函数实现

function strictFunction() {
   "use strict";
    var y = 3.14;   // This is ok
        x = 2.414; // This will cause error
}
通过避免全局变量,可以帮助编写更安全的代码。因此,从技术上讲,这取决于如何使用for循环。参考文献

您还可以使用@RemcoGerlich建议的
let
var
来确定变量的范围

当我把所有的变量都放在函数定义的前面时,我也从面试官那里看到了奇怪的表情

我们应该把所有变量都放到前面吗?或者,如果我们提升除i和j等临时变量之外的所有变量,会怎么样

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

在讨论
let
和ES6之前,我将首先讨论上面的两个参数

在范围顶部声明

这样做的好处是,您总是知道变量声明的位置,并且总是知道父范围。在查看函数时,您可以立即确定整个过程中使用了哪些变量,并且可以从中跟踪它们的使用位置

这种方法的缺点是,根据您的代码结构,从声明变量和使用变量的位置可能有100行,这有时会使调试有点困难,需要您仔细跟踪您认为在函数中使用的变量,因为它可能并不总是在顶部声明的,特别是在

声明与变量的使用位置非常接近

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

这样做的缺点与在顶部声明的优点正好相反。如果您想知道在给定的范围内使用了哪些变量名/标识符,那么您必须进行挖掘
CTRL+F
是您的朋友,但查看位于同一位置的列表会更快

现在让
怎么样?

同样,关于这一点,有两个学派:一个是“let is the new var”,另一个是“let simply允许我们在语法上做我们已经在风格上做的事情”

例如,以以下代码为例:

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

对于(var i=1;i在某个时候,我们可以在任何地方使用
let
,也许你已经可以了。考虑到你的函数不应该超过几行,这真的没关系。@plalx是否编写过AngularJS控制器?或复杂的对象/类定义?@mhodges我构建了许多AngularJS企业应用程序。控制器没有什么不同从其他方面来看。@plalx我希望看到企业应用程序的“不超过几行”控制器。臃肿的控制器问题是Angular2放弃整个控制器概念的主要原因之一。
(let i=1;i是的-这是现代Javascript中更好的样式。需要一点习惯,但您应该总是更喜欢使用
let
const
而不是'var'。是的,IE远远落后。使用transpiler(例如babel、闭包编译器、typescript等)如果这对你的团队是可行的。@Triptych我想我会认为设置一个
con
for (var i = 1; i <= 10; i++) {
   var result = 2 * i;
   console.log(result);
}