var example = "hi"声明了一个变量,它最初也被赋值为undefined,但是当在执行过程中实际到达那行代码时,它被重新赋值为字符串“hi”。 说明代码
function testVariableDeclaration() {
// This behaves 'as expected'....
console.log(test2, 'no value assigned yet'); // --> undefined 'no value assigned yet'
// ....but shouldn't our actual expectation instead be that it'll throw an error since
// it doesn't exist yet? See the final console.log() below!
// As we all know....
test1 = 'global var'; // ....a variable assignment WITHOUT declaration in the current
// scope creates a global. (It's IMPLICITLY declared.)
// But a little counter-intuitively....
test2 = 'not global'; // Although this variable also appears to be assigned without
// declaration like 'test1', the declaration for 'test2' that
// appears *later* in the code gets hoisted so that it's already
// been declared in-scope prior to this assignment.
console.log( test1, window.test1 === test1 ); // --> 'global var' TRUE
console.log( test2, window.test2 === test2 ); // --> 'not global' FALSE
var test2; // As shown by the above console.log() outputs, this variable is scoped.
console.log( test3 ); // Throws a ReferenceError since 'test3' is not declared
// anywhere, as opposed to the first console.log() for 'test2'.
}
1) let example; // this is declaring and initializing with undefined
2) example="hi"; // this is assigning the value to hi
3) let example = "hi" // this is declaring and initializing with "hi"
9条答案
按热度按时间pgvzfuti1#
以下是规范中的一个信息性例外:
var
语句声明的变量的作用域为正在运行的执行上下文的VariableEnvironment。Var变量在其包含的词法环境被示例化时被创建,并在创建时被初始化为undefined
。[...]由具有Initializer的VariableDeclaration定义的变量在执行VariableDeclaration时被分配其Initializer的AssignmentExpression的值,而不是在创建变量时。根据我的阅读,以下几点描述了你在问题中询问的行为(以及术语的“正确”用法):
var foo
)会导致该变量在“词法环境”被示例化后立即被创建。例如,如果该变量在函数体中定义,则该函数是“词法环境”,因此变量创建与函数本身的示例化一致。undefined
初始化:变量被创建[...]并初始化为undefined
这里强调“技术上”,因为如果还提供了一个 * 初始化器 *,这在很大程度上是学术性的。
var foo;
可以存在于函数体中的任何地方,并且将其移动到同一函数中的任何其他地方都不会对函数本身的运行时语义产生影响(无论是否/在何处发生了对foo
的任何实际赋值或其他引用)。如果仍然感到困惑,请重新阅读前面的要点。所以,快速回顾一下:
var
)在其词法环境初始化时 * 始终 * 使用undefined
初始化。希望这能有所帮助(而且我没有严重误解规范!)).
neekobn82#
@jmar777的回答绝对是对规范最好的解释和分解。然而,我发现对于我们这些动手学习的人来说,一些说明性的代码是很有帮助的!;)
基本理念
window.varName = value
)。undefined
的开始 * 赋值 * 进行 * 初始化 *(即使它们在第一行代码中立即被赋值)。因此,初始化对我们来说不是一个重要的术语。我们声明并赋值,JavaScript引擎初始化。
直接回答你问题中的例子:
var example;
声明了一个变量,在初始化过程中该变量被赋值为undefined
。var example = "hi"
声明了一个变量,它最初也被赋值为undefined
,但是当在执行过程中实际到达那行代码时,它被重新赋值为字符串“hi”。说明代码
“范围”对声明/分配的影响
声明和赋值之间的区别更明显的是,* 声明 * 一个变量总是在当前作用域(
myVar
scopeB)内创建一个新变量,即使父作用域(myVar
scopeA)中已经存在同名变量。然后,我们可以在当前作用域的任何位置 assign 一个新值给myVar
scopeB,而无需重新声明它。(此赋值不影响myVar
scopeA的值。)一旦到达scopeB的末尾,myVar
scopeB将不再可用于赋值。另一方面,如果我们在一个给定的作用域中给一个变量赋值,而没有在该作用域中声明它,它将被赋值给“作用域链”中的下一个最高声明(或者如果没有找到更高的声明,则将隐式声明全局)。
因此,一个变量只需要声明一次 * 每个作用域 *,每个声明覆盖父作用域中的任何声明(即它创建不同的变量)。但是如果它在作用域中是唯一的,它 * 必须 * 在作用域中声明。赋值可以根据需要多次发生,但只影响最“接近声明”的变量(因为缺乏更好的术语)。
h5qlskok3#
唯一的区别是
var
语句将初始化任何没有值的声明变量为undefined
。在这两个例子中,你都声明了一个变量。
如果在没有
var
语句的情况下为变量赋值,它将沿着作用域链寻找声明的变量,最终返回到全局window
对象。w46czmvw4#
声明:变量在相应的作用域中(例如,在函数中)使用给定的名称注册。
初始化:当你声明一个变量时,它会自动初始化,这意味着JavaScript引擎会为变量分配内存。
分配:这是当一个特定的值被分配给变量。
来源:SitePoint
eimct9ow5#
这里有一个小东西你错过了。打个比方来理解这个概念是这样的。对于每个变量,必须有一些值分配给它。
所有变量的默认值(如果没有明确提到,则为undefined)
所以第三个语句实际上等于1+2。
现在,可能会出现一个问题,即当语句3是可能的时,为什么我们需要语句1?
原因是扩大了变量的范围。
例如,假设在第8行需要变量。但是该值直到很晚才可用,并且也在代码块中。
通过声明上面的变量,我们增加了变量的作用域,因此它可以在try块之外使用。
PS:这只是一个简单的用法示例。
hof1towb6#
声明基本上意味着向程序中引入一个新的实体。初始化是给一个变量它的第一个值。所以,你上面的例子基本上是正确的。
9gm1akwq7#
直接从MDN获取:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined:
全局undefined属性表示原始值undefined。它是JavaScript的原始类型之一。
简单地在Javascript中声明一个变量,例如
var example
,将其初始化为undefined的原始值。这意味着以下两个表达式是等效的:目前我不知道也无法测试的是,在Web浏览器历史记录中,警报将显示为true。例如,这个警报是否在IE6或一些不知名的黑莓手机上工作?我不能肯定这是普遍的,但它至少在最新版本的Firefox,Chrome和Safari中工作。
niknxzdl8#
这是两件事
var example;
意味着声明了example
,并使用默认值'undefined'
进行了初始化var example = "hi"
表示声明了example
,并使用字符串"hi"
进行了初始化r6vfmomb9#
声明是在程序中引入一个新名称。
初始化指的是值的“赋值”。