在 Javascript 中,我可以在声明之前使用变量吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20220862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 18:01:37  来源:igfitidea点击:

In Javascript, can I use a variable before it is declared?

javascriptvariablesscopeswitch-statement

提问by tjons

I have been wondering for a while if I can use a variable in JS before it is defined, such as the following:

一直在想,是否可以在JS中定义一个变量之前使用它,比如下面这样:

var country = "USA";
switch (country) {
    case "USA":
        country = i;
    case "blach":
        //not finished yet
}
/*
  put a whole
  bunch more code here
*/
var i = 10;

Is this valid? Is it allowed? And if so, what is the technical term for it?

这是有效的吗?允许吗?如果是这样,它的技术术语是什么?

采纳答案by apsillers

This is a technique used by the JavaScript engine called hoisting. The parser will read through the entire function before running it, and any variable declarations (i.e. using the varkeyword) will be executed as if they were at the top of the containing scope. So your code behaves like:

这是 JavaScript 引擎使用的一种称为hoisting 的技术。解析器将在运行之前通读整个函数,并且任何变量声明(即使用var关键字)将被执行,就好像它们在包含范围的顶部一样。所以你的代码表现得像:

var country;
var i;

country = "USA";
switch (country) {
case "USA":
    country = i;
case "blach":
    //not finished yet
}

i = 10;

So, iis declaredthroughout the entire scope, but its value is undefineduntil the i = 10statement runs.

因此,在整个范围内i声明了,但它的值是undefined直到i = 10语句运行为止。

In ECMAScript terms, when a function is invoked, the function's new lexical scope builds its VariableEnvironmentbefore any of the function's code runs. In ECMAScript 10.5, step 8:

在 ECMAScript 术语中,当一个函数被调用时,该函数的新词法作用域会VariableEnvironment在该函数的任何代码运行之前构建它。在ECMAScript 10.5 中,第 8 步

8. For each VariableDeclaration... din code, in source text order do

a. Let dnbe the Identifier in d.

...

i. Call env's CreateMutableBinding concrete method passing dnand configurableBindingsas the arguments.

ii. Call env's SetMutableBinding concrete method passing dn, undefined, and strictas the arguments.

8. 对于每个VariableDeclaration... d代码中,按源文本顺序做

一个。让dn成为 d 中的标识符。

...

一世。调用env的 CreateMutableBinding 具体方法,传递dnconfigureBindings作为参数。

ii. 呼叫ENV的SetMutableBinding具体方法传递DNundefined严格的论证。

This is quite a mouthful, but basically it says:

这是相当一口,但基本上它说:

Before you run a function, look through the function's source code for declarations like var [identifierName].

For each declaration you find, create a new variable in the function's scope with the name [identifierName]used in the declaration and then set its value to undefined

在运行函数之前,请查看函数的源代码以查找诸如var [identifierName].

对于您找到的每个声明,[identifierName]使用声明中使用的名称在函数的作用域中创建一个新变量,然后将其值设置为undefined

回答by adamb

It's called variable hoisting, and it's a good concept to understand as it can occasionally create bugsthat are hard to track down.

它被称为变量提升,这是一个很好理解的概念,因为它偶尔会产生难以追踪的错误

For example:

例如:

var stuff = 'stuff';
function() {
 console.log(stuff); //outputs 'undefined'
 var stuff = 'other stuff';
 console.log(stuff); //outputs 'other stuff'
}

The first console.logoutputs undefinedbecause the var stuffin the function was hoistedto the top of the function.

第一个console.log输出undefined是因为stuff函数中的 var被提升到函数的顶部。

//theoretical compiled output
var stuff = 'stuff';
function() {
 var stuff; //has not been defined
 console.log(stuff);
 stuff = 'other stuff'; //defined here
 console.log(stuff);
}

Without knowledge of variable hoisting, this result may be confusing.

如果不了解变量提升,这个结果可能会令人困惑。

For this reason, if you look at professionally developed JavaScript code, typically you'll see all variables in a function are declared at the top.

出于这个原因,如果您查看专业开发的 JavaScript 代码,通常您会看到函数中的所有变量都在顶部声明。

回答by Moritz Roessler

Yes. In JavaScript, variables are hoisted

是的。在 JavaScript 中,变量被提升

A variable statement declares variables that are created as defined in 10.5. Variables are initialised to undefined when created. A variable with an Initialiser is assigned the value of its AssignmentExpression when the VariableStatement is executed, not when the variable is created.ES5 §12.2
Where 10.5 step 8 is the part of interest

变量语句声明按照10.5 中定义创建的变量。变量在创建时初始化为 undefined。具有 Initialiser的变量在执行 VariableStatement 时被分配其 AssignmentExpression 的值,而不是在创建变量时。ES5 §12.2
其中 10.5 步骤 8 是感兴趣的部分

回答by Mark Walters

The guys answers are correct. for your example however it is worth noting that countryis undefined. as aspillers has mentioned your code behaves as below

小伙伴们的回答是正确的。但是,对于您的示例,值得注意的countryundefined. aspilers 已经提到你的代码行为如下

var country;
var i;

country = "USA";

switch (country) {
case "USA":
    country = i;
case "blach":
    //not finished yet
}

i = 10;
alert(country) //undefined;

but when your casestatement ran for "USA", iwas undefined so this was assigned to country. try it here in this fiddle.

但是当您的case语句为“USA”运行时,i未定义,因此将其分配给country. 在这个小提琴中尝试一下。

I guess that you just need to be aware that although the variable declarations are hoisted, the value assignments aren't.

我想您只需要注意,虽然变量声明被提升,但值分配不是。