我想知道一段时间,我是否可以在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;
这是有效的吗?是允许的吗?如果是,它的技术术语是什么?
我想知道一段时间,我是否可以在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;
这是有效的吗?是允许的吗?如果是,它的技术术语是什么?
5条答案
按热度按时间nzkunb0c1#
这是JavaScript引擎使用的一种技术,叫做 * howing *。解析器在运行函数之前会通读整个函数,并且任何变量声明(例如使用
var
关键字)都会被执行,就好像它们位于包含作用域的顶部一样。因此,代码的行为如下:因此,
i
在整个作用域中都是 * 声明 * 的,但是在i = 10
语句运行之前,它的值是undefined
。在ECMAScript术语中,当调用函数时,函数的新词法作用域在函数的任何代码运行之前构建其
VariableEnvironment
。在ECMAScript 10.5中,步骤8:8.对于 code 中的每个 VariableDeclaration... d,按源文本顺序执行以下操作
a.令 dn 为d中的标识符。
...
i.调用 env 的CreateMutableBinding具体方法,传递 dn 和 configurableBindings 作为参数。
ii.调用 env 的SetMutableBinding具体方法,传递 dn、
undefined
和 strict 作为参数。这句话有点拗口,但基本上是这样说的:
在运行函数之前,请查看函数的源代码中是否有
var [identifierName]
之类的声明。对于找到的每个声明,在函数作用域中创建一个新变量,名称为声明中使用的
[identifierName]
,然后将其值设置为undefined
pkbketx92#
它被称为variable hoisting,这是一个很好的概念,因为它偶尔会产生难以跟踪的bug。
例如:
第一个
console.log
输出undefined
,因为函数中的变量stuff
被提升到函数的顶部。如果不了解变量提升,此结果可能会混淆。
因此,如果查看专业开发的JavaScript代码,通常会看到函数中的所有变量都在顶部声明。
rpppsulh3#
是的。在JavaScript中,变量被提升
变量语句声明按照10.5中的定义创建的变量。变量在创建时被初始化为undefined。带有Initialiser的变量在执行VariableStatement时被赋值给AssignmentExpression**,而不是在创建变量时。ES5 §12.2
其中10.5步骤8是感兴趣的部分
fgw7neuy4#
这些人的答案是正确的。但是对于您的示例,值得注意的是
country
是undefined
。正如aspillers所提到的,您的代码行为如下但是当你的
case
语句为“USA”运行时,i
是未定义的,所以它被赋值给country
。在这个fiddle中尝试它。我猜您只需要注意,虽然变量声明被提升了,但赋值却没有。
zdwk9cvp5#
是的,你可以在声明一个变量之前使用它。在JavaScript中这叫做提升。但要记住的一点是,只有变量的声明被提升,而不是它的初始化。这意味着你将不能使用变量的值,你将在后面的代码中赋值。例如,
因此,即使在声明之前使用
myVar
,也不会出现错误(myVar未定义)。但myVar的控制台日志值将是未定义的。在代码执行开始时,变量已声明,但其赋值尚未声明。因此,JS引擎会将上面的代码块视为它会将文件中使用的所有变量的声明放在代码的顶部。