简体   繁体   English

函数头部的Javascript变量声明

[英]Javascript variable declarations at the head of a function

I've been told that javascript variables should all come before they are used in a function, such that: 我被告知javascript变量应该在它们用于函数之前全部出现,这样:

function contrived() {
  var myA, myB;

  myA = 10;
  myB = 20;

  return myA + myB;
}

Is prefered over: 优先:

function furtherContrivance() {
  var myA = 10;
  var myB = 20;

  return myA + myB;
}

Is this the case? 是这样的吗? And why is that? 为什么是这样?

I guess some people might prefer the former style because that's how it works inside. 我想有些人可能更喜欢前一种风格,因为它的内部工作原理。 All local variables exist for the entire lifetime of the function, even if you use var to declare them in the middle of the function. 即使您使用var在函数的中间声明它们,函数的整个生命周期中都存在所有局部变量。

There's nothing wrong with declaring variables later in the function, syntax-wise, it might just be confusing as the variables will then exist before the line that declares them. 在函数中稍后声明变量没有任何问题,在语法方面,它可能只是令人困惑,因为变量将在声明它们的行之前存在。 Hence this function: 因此这个功能:

function bar() {
    alert(foo); // Alerts "undefined". Not an error because the variable does exist.
    var foo = 10;
    alert(foo); // Alerts the value 10.
}

Is equivalent to this: 相当于:

function bar() {
    var foo;
    alert(foo);
    foo = 10;
    alert(foo);
}

Another related fact is that nested function definitions (done using function foo() { ... } ) will get moved to the top of the containing function as well, so they will be available even if the code that calls them comes before them. 另一个相关的事实是,嵌套函数定义(使用function foo() { ... } )也将被移动到包含函数的顶部,因此即使调用它们的代码在它们之前,它们也将可用。

There is no difference in this case between this two. 这两者之间没有区别。 I'd go with: 我会去:

function furtherContrivance() {
  var myA = 10,
      myB = 20;

  return myA + myB;
}

which is knows as single var pattern in javascript. 这在javascript中被称为single var pattern

What you really need to take care of is defining your variables in the beginning of your functions. 您真正需要注意的是在函数的开头定义变量。 There is a thing in javascript called variables hoisting which means that variable definitions used in function "raise" on top. 在javascript中有一个称为variables hoisting的东西,这意味着函数“up”中使用的变量定义位于顶部。 It's best described by an example: 最好用一个例子来描述:

var x = 'global'; // global (bounded to a global object which is window in browsers)
function func() { 
    alert(x); // undefined (you expected 'global', right?)
    var x = 'local';
    alert(x); // local
}
func();

what really happens is called (as I said) variables hoisting (definition of x raises on top), so the code above is actually the same as: 真正发生的事情被调用(如我所说) variables hoistingx定义在顶部引起),所以上面的代码实际上与:

var x = 'global';
function func() {
    var x; // definition of `x` raised on top (variables hoisting)
    alert(x); // undefined in a local scope
    x = 'local';
    alert(x);
}

What a javscript interpreter does is it looks inside a function, gathers locally defined variables and raises them on top - this might be a good reason why you should use single var pattern . javscript解释器的作用是查看函数内部,收集本地定义的变量并将它们置于顶部 - 这可能是您应该使用single var pattern一个很好的理由。

Yes, the variable declaration should come at the top of the function: 是的,变量声明应该位于函数的顶部:

function foo() {
  var a, b;
}

However, initializing variables can be part of the declaration: 但是,初始化变量可以是声明的一部分:

function foo() {
  var a = 10, b = 20;
}

The reasoning behind declaring all variables at the top of the function where they are used is to avoid scope confusion. 在函数顶部声明所有变量的原因是为了避免范围混淆。

Here is an example of bad code: 以下是错误代码的示例:

function foo() {
  var b;
  for (var i = 0; i < 5; i++) {
    var a;
    a = b = i;
    setTimeout(function(){
      console.log(a, b);
    }, 1000);
  }
}

If you execute the code, it will log 4, 4 5 times, rather than counting up. 如果执行代码,它将记录4, 4次, 4, 4次,而不是计数。 This is because only functions act as closures and introduce new scope. 这是因为只有函数充当闭包并引入新的范围。 In JavaScript, any var declaration within a function gets executed at the beginning of the function. 在JavaScript中,函数中的任何var声明都在函数的开头执行。

This makes the above error much more visible: 这使得上述错误更加明显:

function foo() {
  var a, b, i;
  for (i = 0; i < 5; i++) {
    a = b = i;
    setTimeout(function(){
      console.log(a, b);
    }, 1000);
  }
}

In the example you give this is absolutely not the case. 在示例中,您绝对不是这样。 In a language like Javascript, it will be more of a developer preference, but it won't have any impact on the result. 在像Javascript这样的语言中,它将更多地是开发人员的偏好,但它不会对结果产生任何影响。

Yes, place them at the top. 是的,把它们放在顶部。 It adds to code clarity. 它增加了代码清晰度。

Try this example: 试试这个例子:

var x = 1;

(function() {

    x++;
    alert( x );  // What will this alert show?

    var x = 'done';
    alert( x );

})();

Looks like it should alert 2 , but it alerts NaN . 看起来它应该警告2 ,但它警告NaN

This is because the variable declaration is hoisted to the top, but the initialization stays in the same place. 这是因为变量声明被提升到顶部,但初始化保持在同一个地方。

So what is actually happening is: 所以实际发生的是:

var x = 1;

(function() {
    var x;

    x++;
    alert( x );  // What will this alert show? NaN

    x = 'done';
    alert( x );

})();

...which makes the NaN expected. ......这使NaN成为可能。

For readability, it's definitely preferred. 为了便于阅读,它绝对是首选。

However, Javascript "hoists" declarations. 但是,Javascript“提升”声明。 Hoisting means that vars and functions will be automatically moved to the top of their scope. 吊装意味着变量和功能将自动移动到其范围的顶部。 This allows you to do things such as use a function before it's declared: 这允许您在声明之前执行诸如使用函数之类的操作:

function myScope()
{
   test();

   function test()
   {
      //...
   }
}

This can lead to some confusion, especially if variables within block scopes are declared. 这可能会导致一些混淆,尤其是在声明块范围内的变量时。 For example: 例如:

for(var i in foo)
{
   var e = myFunc();
}

The declaration of e will be hoisted to the top of the closure, and e will be initialized to undefined. e的声明将被提升到闭包的顶部,e将被初始化为undefined。 This allows for some interesting non-intuitive situations, such as: 这允许一些有趣的非直观情况,例如:

if(!foo) //Will not throw reference error because foo is declared already
{
   var foo = {};
}

So, regardless of how you declare your variables, they'll all get "moved up" to the top of the function anyway. 因此,无论您如何声明变量,它们都会“升级”到函数的顶部。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM