javascript 声明和初始化一个变量

hrysbysz  于 2023-05-27  发布在  Java
关注(0)|答案(9)|浏览(341)

我很想知道声明变量和初始化变量之间的区别。例如

var example; // this is declaring

var example = "hi" // initializing? Or just "adding a value"?

我不认为我是对的,但每一个的定义到底是什么?或者它们的意思基本上是一样的?

pgvzfuti

pgvzfuti1#

  • 编辑:@ThisClark在评论中说了一些话,我去证明他错了,在阅读规范后,我学到了一些东西:*

以下是规范中的一个信息性例外:
var语句声明的变量的作用域为正在运行的执行上下文的VariableEnvironment。Var变量在其包含的词法环境被示例化时被创建,并在创建时被初始化为undefined。[...]由具有Initializer的VariableDeclaration定义的变量在执行VariableDeclaration时被分配其Initializer的AssignmentExpression的值,而不是在创建变量时。
根据我的阅读,以下几点描述了你在问题中询问的行为(以及术语的“正确”用法):

  • 一个 * 变量声明 *(例如var foo)会导致该变量在“词法环境”被示例化后立即被创建。例如,如果该变量在函数体中定义,则该函数是“词法环境”,因此变量创建与函数本身的示例化一致。
  • 显然,variable declarations 可能会也可能不会使用 initializer(即解析为变量初始值的右侧表达式)创建。这是一个相当不规范的使用术语“初始值”,虽然…让我们再深入一点:
    • 技术上 *,根据这里的规范注解,所有变量都使用值undefined初始化:

变量被创建[...]并初始化为undefined
这里强调“技术上”,因为如果还提供了一个 * 初始化器 *,这在很大程度上是学术性的。

  • 基于我们已经介绍过的内容,应该理解的是,语句var foo;可以存在于函数体中的任何地方,并且将其移动到同一函数中的任何其他地方都不会对函数本身的运行时语义产生影响(无论是否/在何处发生了对foo的任何实际赋值或其他引用)。如果仍然感到困惑,请重新阅读前面的要点。
  • 行为的最后一点是最直观的部分,那就是 * 初始化器 * 的 * 赋值 *。当这行代码实际上被执行时,这个赋值就发生了(同样,这与变量在技术上被创建的时间点不同)。

所以,快速回顾一下:

    • 所有 * 变量声明(使用var)在其词法环境初始化时 * 始终 * 使用undefined初始化。
  • 这个初始化可能不算一个 * 赋值 *,在技术意义上(哈,@ThisClark,你 * 错了!!).:)
  • 分配是最简单的部分,因为它们的行为方式(以及在时间点)符合您的预期。

希望这能有所帮助(而且我没有严重误解规范!)).

neekobn8

neekobn82#

@jmar777的回答绝对是对规范最好的解释和分解。然而,我发现对于我们这些动手学习的人来说,一些说明性的代码是很有帮助的!;)

基本理念

  • “Declaration”使变量在给定范围内可用。
  • “赋值”在代码中的该位置为变量提供特定值。如果试图将一个值赋给一个从未在该作用域或父作用域中声明过的变量,则该变量将在全局作用域中隐式声明(等于键入window.varName = value)。
  • 可以说,“初始化”是发生在“幕后”或“幕后”的事情。在运行时,所有 * 声明的 * 变量都以undefined的开始 * 赋值 * 进行 * 初始化 *(即使它们在第一行代码中立即被赋值)。

因此,初始化对我们来说不是一个重要的术语。我们声明并赋值,JavaScript引擎初始化。
直接回答你问题中的例子:

  • var example;声明了一个变量,在初始化过程中该变量被赋值为undefined
  • 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'.
}

“范围”对声明/分配的影响

声明和赋值之间的区别更明显的是,* 声明 * 一个变量总是在当前作用域(myVarscopeB)内创建一个新变量,即使父作用域(myVarscopeA)中已经存在同名变量。然后,我们可以在当前作用域的任何位置 assign 一个新值给myVarscopeB,而无需重新声明它。(此赋值不影响myVarscopeA的值。)一旦到达scopeB的末尾,myVarscopeB将不再可用于赋值。
另一方面,如果我们在一个给定的作用域中给一个变量赋值,而没有在该作用域中声明它,它将被赋值给“作用域链”中的下一个最高声明(或者如果没有找到更高的声明,则将隐式声明全局)。
因此,一个变量只需要声明一次 * 每个作用域 *,每个声明覆盖父作用域中的任何声明(即它创建不同的变量)。但是如果它在作用域中是唯一的,它 * 必须 * 在作用域中声明。赋值可以根据需要多次发生,但只影响最“接近声明”的变量(因为缺乏更好的术语)。

h5qlskok

h5qlskok3#

唯一的区别是var语句将初始化任何没有值的声明变量为undefined
在这两个例子中,你都声明了一个变量。
如果在没有var语句的情况下为变量赋值,它将沿着作用域链寻找声明的变量,最终返回到全局window对象。

w46czmvw

w46czmvw4#

声明:变量在相应的作用域中(例如,在函数中)使用给定的名称注册。
初始化:当你声明一个变量时,它会自动初始化,这意味着JavaScript引擎会为变量分配内存。
分配:这是当一个特定的值被分配给变量。

let x; // Declaration and initialization
x = "Hello World"; // Assignment

// Or all in one
let y = "Hello World";

来源:SitePoint

eimct9ow

eimct9ow5#

这里有一个小东西你错过了。打个比方来理解这个概念是这样的。对于每个变量,必须有一些值分配给它。
所有变量的默认值(如果没有明确提到,则为undefined)

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"

所以第三个语句实际上等于1+2。
现在,可能会出现一个问题,即当语句3是可能的时,为什么我们需要语句1?
原因是扩大了变量的范围。
例如,假设在第8行需要变量。但是该值直到很晚才可用,并且也在代码块中。

1) {
2)  let a;
3)  try{
4)   a=someFunctionWhichMayThroeException();
5)  }
6)    catch(e){
7)         a=100;
8)  }
9)  someFunctionOnA(a);// the variable is required here
10)
11)  }

通过声明上面的变量,我们增加了变量的作用域,因此它可以在try块之外使用。
PS:这只是一个简单的用法示例。

hof1towb

hof1towb6#

声明基本上意味着向程序中引入一个新的实体。初始化是给一个变量它的第一个值。所以,你上面的例子基本上是正确的。

9gm1akwq

9gm1akwq7#

直接从MDN获取:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined
全局undefined属性表示原始值undefined。它是JavaScript的原始类型之一。
简单地在Javascript中声明一个变量,例如var example,将其初始化为undefined的原始值。这意味着以下两个表达式是等效的:

//equivalent expressions
var ex1;
var ex2 = undefined;

//true!
alert(ex2 === ex1);

目前我不知道也无法测试的是,在Web浏览器历史记录中,警报将显示为true。例如,这个警报是否在IE6或一些不知名的黑莓手机上工作?我不能肯定这是普遍的,但它至少在最新版本的Firefox,Chrome和Safari中工作。

niknxzdl

niknxzdl8#

var example; // this is declaring

var example = "hi" // initializing? Or just "adding a value"?

这是两件事
var example;意味着声明了example,并使用默认值'undefined'进行了初始化
var example = "hi"表示声明了example,并使用字符串"hi"进行了初始化

r6vfmomb

r6vfmomb9#

声明是在程序中引入一个新名称。

var test;        // Is this a declaration ?

初始化指的是值的“赋值”。

var test = {first:"number_one"}  // Now that object is initialized with value

相关问题