在JavaScript中在函数体顶部声明变量的好处

时间:2014-09-20 05:08:13

标签: javascript

我正在阅读Douglas Crockford的书"Javascript: The Good Parts"。他正在讨论范围,并说JS没有块范围:

  

在许多现代语言中,建议声明变量   尽可能晚,在第一个使用点。结果证明是这样的   对Javascript的错误建议,因为它缺少块范围。所以相反,它   最好声明顶部函数中使用的所有变量   功能体。

但是,我想不出一个很好的例子,为什么这个陈述有意义,看到一些验证这个陈述的例子真的很好。

4 个答案:

答案 0 :(得分:6)

在顶部声明变量有助于避免这样的情况:

function outer() {
  var i = 50;

  function inner() {
    alert(i);
    var i= 30;
  }
  inner();
}

outer();

很多人都希望警报显示50,他们会惊讶地看到undefined。这是因为i变量是在inner函数中声明的,但直到alert之后才初始化。因此它具有完整的功能范围,即使它在初次使用后被声明。

答案 1 :(得分:3)

在函数顶部声明变量,作为记录在一个地方使用的所有变量的方法。

它还可以避免由于某人想象变量是实际上没有的块块而导致的混淆,如下所示:

var i=0;
if (true) {
   var i=1;
}
// what is i? C programmer might imagine it's 0.

如果变量也在声明时被初始化,那么将声明置于顶部可以避免初始化时间的潜在问题:

console.log(foo);
var foo = 1;

在这种情况下,foo被提升,因此它在console.log时声明,但尚未初始化。所以这有点像

var foo;
console.log(foo); // no ReferenceError, but undefined
foo = 1;

答案 2 :(得分:0)

从我的观点来看,由于javascript没有块范围,因此在函数顶部声明所有变量会使您找到更容易使用的变量,因为您可以重用其他变量。

示例:

function test(){
    var pages = [
        'www.stackoverflow.com',
        'www.google.com'
    ];

    var users = [
        'John',
        'Bob'
    ];

    for (var page = 0; page < pages.length; page++) {
        console.log(pages[page]);
    };

    for (var user = 0; user < users.length; user++) {
        console.log(users[user]);
    };
}

可以更改为:

function test(){
    var index, pages, users;

    pages = [
        'www.stackoverflow.com',
        'www.google.com'
    ];

    users = [
        'John',
        'Bob'
    ];

    for (index = 0; index < pages.length; index++) {
        console.log(pages[index]);
    };

    for (index = 0; index < users.length; index++) {
        console.log(users[index]);
    };
}

并从内存中保存一个变量空间。

在如此小的功能中,主要观点可能不明显,但想象一下整个项目有千行代码。这可能会使您的代码运行得更快。

答案 3 :(得分:0)

这并不总是一个好主意。这取决于你正在做什么。当他们说没有必要声明"top level"变量时,他们的意思是,它并不重要。它在函数内部很重要。请考虑以下示例:

varOne = 1; varTwo = 2; varThree = 3; // undeclared
function lameFunc(){
  var varOne = 'Something'; // does no affect varOne at the top level
  return varOne;
}

同样:

var varOne = 1, varTwo = 2, varThree = 3; // declared
function lameFunc(){
  var varOne = 'Something'; // does no affect varOne at the top level
  return varOne;
}

当然,使用关键字var更容易看到变量,并且由于"top level"没有任何不利影响,建议使用。

请注意,当我更改lameFunc()时,无论如何都会影响更高的杠杆var

function lameFunc(){
  /* varOne is effected at the higher level whether or not `var` is declared
    above as in `varOne = 1` or `var varOne = 1` */
  varOne = 'Something';
  return varOne;
}

此外,如果您在var someInputVal = document.getElementById('someInput').value;之类的事件之外声明一个变量,那么假设您想要获取元素的值。您希望在var中声明Element.onclick = function(){/* in here */},因为在您点击Element之前输入可能已更改。在处理您的事件的函数之外声明var someInput = document.getElementById('someInput');可能是可以的,如果元素没有成为undefined那么您可以访问类似的内容:

var doc = document, bod = doc.body;
function E(e){
  return doc.getElementById(e);
}
var someInput = E('someInput'), someInputVal = someInput.value;
E('clickButton').onclick = function(){
  console.log(someInputVal); // will not be what document.getElementById('someInput').value is if it was changed before clicking
  var declared = someInput.value;
  console.log(declared);
}