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

apeeds0o  于 2023-01-24  发布在  Java
关注(0)|答案(5)|浏览(105)

我想知道一段时间,我是否可以在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;

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

nzkunb0c

nzkunb0c1#

这是JavaScript引擎使用的一种技术,叫做 * howing *。解析器在运行函数之前会通读整个函数,并且任何变量声明(例如使用var关键字)都会被执行,就好像它们位于包含作用域的顶部一样。因此,代码的行为如下:

var country;
var i;

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

i = 10;

因此,i在整个作用域中都是 * 声明 * 的,但是在i = 10语句运行之前,它的值是undefined
在ECMAScript术语中,当调用函数时,函数的新词法作用域在函数的任何代码运行之前构建其VariableEnvironment。在ECMAScript 10.5中,步骤8:
8.对于 code 中的每个 VariableDeclaration... d,按源文本顺序执行以下操作
a.令 dn 为d中的标识符。
...
i.调用 env 的CreateMutableBinding具体方法,传递 dnconfigurableBindings 作为参数。
ii.调用 env 的SetMutableBinding具体方法,传递 dnundefinedstrict 作为参数。
这句话有点拗口,但基本上是这样说的:
在运行函数之前,请查看函数的源代码中是否有var [identifierName]之类的声明。
对于找到的每个声明,在函数作用域中创建一个新变量,名称为声明中使用的[identifierName],然后将其值设置为undefined

pkbketx9

pkbketx92#

它被称为variable hoisting,这是一个很好的概念,因为它偶尔会产生难以跟踪的bug
例如:

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

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

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

如果不了解变量提升,此结果可能会混淆。
因此,如果查看专业开发的JavaScript代码,通常会看到函数中的所有变量都在顶部声明。

rpppsulh

rpppsulh3#

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

fgw7neuy

fgw7neuy4#

这些人的答案是正确的。但是对于您的示例,值得注意的是countryundefined。正如aspillers所提到的,您的代码行为如下

var country;
var i;

country = "USA";

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

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

但是当你的case语句为“USA”运行时,i是未定义的,所以它被赋值给country。在这个fiddle中尝试它。
我猜您只需要注意,虽然变量声明被提升了,但赋值却没有。

zdwk9cvp

zdwk9cvp5#

是的,你可以在声明一个变量之前使用它。在JavaScript中这叫做提升。但要记住的一点是,只有变量的声明被提升,而不是它的初始化。这意味着你将不能使用变量的值,你将在后面的代码中赋值。例如,

console.log(myVar); //undefined
myVar = 10;
var myVar;

因此,即使在声明之前使用myVar,也不会出现错误(myVar未定义)。但myVar的控制台日志值将是未定义的。在代码执行开始时,变量已声明,但其赋值尚未声明。因此,JS引擎会将上面的代码块视为

var myVar;
console.log(myVar); //undefined
myVar = 10;
var myVar;

它会将文件中使用的所有变量的声明放在代码的顶部。

相关问题