15

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

var example; // this is declaring

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

我不认为我就在那里,但每个人的定义到底是什么?还是它们基本上是同一个意思?

4

9 回答 9

18

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

这是除规范之外的信息:

var语句声明范围为运行执行上下文的 VariableEnvironment 的变量。var 变量在它们包含的词法环境被实例化undefined时创建,并在创建时被初始化。[...] 由具有 Initializer 的 VariableDeclaration 定义的变量在执行 VariableDeclaration 时分配其 Initializer 的 AssignmentExpression 的值,而不是在创建变量时。

根据我对此的阅读,以下几点描述了您在问题中询问的行为(以及术语的“正确”用法):

  • 一旦“词法环境”被实例化,变量声明(例如,var foo)就会导致该变量被创建。例如,如果该变量是在函数体中定义的,那么该函数就是“词法环境”,因此变量的创建与函数本身的实例化一致。

  • 显然,变量声明可能会或可能不会使用初始化程序(即,解析为变量初始值的右手表达式)创建。这是术语“初始值”的一个非常非规范的用法,但是......让我们再深入研究一下:

  • 从技术上讲,根据此处的规范说明,所有变量都使用以下值初始化undefined

    变量被创建 [...] 并被初始化为 undefined

    强调“技术上”,因为如果还提供了初始化程序,这在很大程度上是学术性的。

  • 根据我们已经介绍的内容,应该理解该语句var foo;可以存在于函数体内的任何位置,并且将其移动到同一函数中的任何其他位置不会对函数本身的运行时语义产生影响(不管 if/任何实际分配或其他参考发生的foo地方)。如果这仍然令人困惑,请重新阅读前面的要点。

  • 最后一点行为是最直观的部分,那就是初始化器的赋值。该赋值发生在实际执行该行代码时(同样,从技术上讲,这与创建变量的时间点不同)。

因此,快速回顾一下:

  • 所有变量声明(使用var总是在初始化undefined它们的词法环境时被初始化。
  • 从技术意义上讲,这种初始化可能不算作分配(哈,@ThisClark,你错!!)。:)
  • 分配是最容易的部分,因为它们的行为方式(以及在时间点)是您期望的。

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

于 2015-07-30T02:56:35.017 回答
13

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


基本理念

  • “声明”使变量在给定范围内可用。
  • “赋值”在代码中的该位置为变量提供特定值。如果您尝试将值分配给从未在该范围或父范围中声明的变量,则该变量将在全局范围内隐式声明(等于 typing 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 ) 中已经存在同名变量。然后我们可以在当前范围内的任何点为scopeB分配一个新值,而无需重新声明它。(此分配不影响scopeA的值。)一旦到达 scopeB 的末尾,scopeB不再可用于分配。myVarmyVarmyVar

另一方面,如果我们在给定范围内为变量赋值而不在该范围内声明它,它将被分配给“范围链”中的下一个最高声明(或者全局将被隐式如果没有找到更高的声明,则声明)。

因此,一个变量只需要在每个作用域中声明一次,每个声明都覆盖在父作用域中所做的任何声明(即它创建一个不同的变量)。但如果它是该范围唯一的,则必须在范围内声明它。赋值可以根据需要发生多次,但只会影响最“密切声明”的变量(因为没有更好的术语)。

于 2018-01-01T20:17:33.017 回答
0

唯一的区别是该var语句将初始化任何没有值的声明变量undefined

在这两个示例中,您都在声明一个变量。

如果在没有var语句的情况下为变量赋值,它将沿着作用域链查找已声明的变量,最终回退到全局window对象。

于 2015-07-30T03:54:38.450 回答
0

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

于 2015-07-30T02:55:31.063 回答
0

您在这里缺少一件小事。理解这个概念的类比是这样的。对于每个变量,都必须为其分配一些值。

所有变量的默认值(如果没有明确提到是未定义的)

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:这只是一个简单的用法示例。

于 2015-07-30T04:03:03.193 回答
0

直接取自 MDN: https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined :

全局未定义属性表示未定义的原始值。它是 JavaScript 的原始类型之一。

只需在 Javascript 中声明一个变量,例如var example将其初始化为 undefined 的原始值。这意味着以下两个表达式是等价的:

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

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

我目前不知道也无法测试的是,警报将在多远的网络浏览器历史记录中显示为真。例如,此警报是否适用于 IE6 或一些不起眼的黑莓手机?我不能肯定这是通用的,但在撰写本文时它至少适用于最新版本的 Firefox、Chrome 和 Safari。

于 2015-07-30T03:05:15.163 回答
0

声明:在相应范围内(例如,在函数内)使用给定名称注册变量。

初始化:当你声明一个变量时,它会自动初始化,这意味着 JavaScript 引擎会为变量分配内存。

赋值:这是将特定值分配给变量的时候。

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

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

资料来源:SitePoint

于 2021-09-10T04:37:31.987 回答
-1

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

var test;        // Is this a declaration ?

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

var test = {first:"number_one"}  // Now that object is initialized with value
于 2015-07-30T02:58:47.080 回答
-2

宣言

声明意味着创建一个变量。必须声明程序中使用的每个变量。

例如:

var a;

● 当您声明一个变量时,您在计算机内存中为 (a) 保留了一个空间;

● 当您稍后提及单词 (a) 时,程序知道它在内存中保留了哪个确切位置。

任务

声明完成后,使用赋值运算符 (=) 为变量赋值(设置)。

例如:

var a;
a=5;

● 赋值语句(a=5) 将值存储在变量中

  • a 被赋值为 5
  • a 取值为 5
  • a 现在是 5

什么是赋值运算符?

单个等号的 (=) 名称是赋值运算符。

初始化

当您声明一个变量并在声明时赋值时,它称为初始化变量。(初始化=声明+赋值)

例如:

var b = 10;

JavaScript 行为

在 JavaScript 中,如果一个变量已被声明,但尚未被赋值,则自动赋值为 undefined。所以我们可以在变量被声明的时候保持不变,它在词法环境中初始化为未定义。

第一个例子:

var x; 

- 当我们声明变量 x 时,它在词法环境中初始化为 undefined。

第二个例子: 当我们初始化变量时,

var x = "hello";

-在开始时,它被分配一个未定义的值

- 但是当在执行过程中实际到达那行代码时,它会被重新分配给字符串“hello”。

于 2021-08-13T11:45:33.927 回答