在本地范围内初始化 JavaScript 变量

Initializing a JavaScript variable in the local scope

本文关键字:JavaScript 变量 初始化 范围内      更新时间:2023-09-26

我正在研究Javascript中的变量作用域,并遇到了变量声明和变量初始化之间的区别。通过与我认识的开发人员交谈,我的理解是,在变量声明之前编写var会将变量分配给局部范围,而在声明变量之前不编写var会将变量分配给全局范围。这是真的吗?

如果在声明变量之前编写 var 确实将变量分配给局部作用域,那么在初始化变量以将其保留在本地作用域中时,是否需要稍后编写var?例如:

var someVariable;
// Do some things with JavaScript
someVariable = 'Some Value'

由于我用 var 在本地范围内声明了someVariable,但随后在不使用 var 的情况下初始化了someVariable,JavaScript 是否认为我只是在本地范围内初始化了一个变量,或者我在局部范围内声明了一个变量,然后在全局范围内声明初始化了另一个变量?

稍后,当我想再次更改 someVariable 的值时,我是否需要在变量表达式之前编写 var,或者 JavaScript 会知道我正在更改已声明的局部变量的值?从技术上讲,JavaScript 如何知道我何时更改已声明的局部变量的值,以及何时声明和初始化全局变量?

var something = "Initial value."

这意味着:"在局部范围内创建一个变量并为其提供初始值"。本地作用域表示在其中使用此语句的函数。

something = "New value."

这意味着:"在最近的范围内找到变量'某物',并为其分配一个新值"。如果您使用第二个语句而不使用第一个语句,则该语句将在逐渐增大的作用域中查找something的任何定义(包含您的函数的函数,如果存在,包含该函数的函数等,直到它到达全局范围(。如果它找到某些东西,它将分配给一个已经存在的变量。如果它没有找到任何内容,它将创建一个具有该名称的全局变量。

如果首先使用 var,则只需确保此搜索始终在本地范围停止。

这些是相同的:

var x;
// ...
x = 1;

。和。。。

var x = 1;

两者都在局部作用域中定义一个变量并为其赋值。 如果您想稍后在同一范围内更改变量的值,您只需按名称引用它:

x = 2;

但是,如果您位于不同的范围内,除非变量首先在全局范围内声明,否则您将无法访问它(它"超出范围"(。 尝试这样做将在全局范围内定义具有该名称的变量。

function a(){
    var x = 1;
}
function b(){
    x = 2;  // 'x' in a is out of scope, doing this declares a new 'x' in global scope
}
a();
b();
在声明

的同一作用域中引用变量时,不需要在它前面加上 var 前缀,但您可以:

var x = 1;
// ...
var x = 2;

。没有必要这样做。 虽然它将 2 分配给 'x',但它在逻辑上没有影响,因为 var 已经在局部范围内。 但是,如果x已在全球范围内声明:

var x = 1;
function a(){
    var x = 2;
    console.log(x);
}
a();
console.log(x);

这将首先打印"2",然后打印"1"。 通过在函数中引用前面带有var x,它将局部范围应用于变量。 函数完成后,变量的原始作用域将恢复(或者重新作用域丢失,如果你想以这种方式看待它(。 感谢@zzzzBov指出这一点。

希望这有帮助。

我的理解是,在变量声明之前编写 var 会将变量

分配给局部范围,而在声明变量之前不编写 var 会将变量分配给全局范围。这是真的吗?

不完全是。

function foo() {
    var a = 1;
    function bar() {
        a = 2; // Still in the scope of foo, not a global
    }
}

由于我用 var 在本地范围内声明了 someVariable,但随后在不使用 var 的情况下初始化了 someVariable,JavaScript 是否认为我只是在本地范围内初始化了一个变量,或者我在局部范围内声明了一个变量,然后在全局范围内声明并初始化了另一个变量?

该示例中只有一个someVariable

稍后,当我想再次更改某个变量的值时,我是否需要在变量表达式之前编写 var

var为整个函数限定变量的范围,无论它出现在函数中的哪个位置。

如果使用 var 定义变量,则可以引用同一变量,而无需一遍又一遍地使用 var 关键字。这些引用相同的变量:

var someVariable;
//...code...
someVariable = 'rawr';

如果每次更改变量时都使用 var 关键字,则不会获得单独的变量。最新的声明只会覆盖最旧的声明。因此,除了初始化之外,使用 var 关键字没有任何意义。要更改 someVariable 的值,您可以像上面的例子一样对变量名进行赋值。

基本上,如果该作用域中没有同名的变量,则使用 var 将创建一个新变量。

现在以这段代码为例:

var someVariable = 'initialized';
function test1(){
  //this someVariable will be a new variable since we have the var keyword and its in a different scope
  var someVariable = 'test1';
  console.log(someVariable);
}
function test2(){
  //because there is no var keyword this refers to the someVariable in the parent scope
  someVariable = 'test2';
  console.log(someVariable);
}
console.log(someVariable); //initialized
test1(); //test1
console.log(someVariable); //initialized
test2(); //test2
console.log(someVariable); //test2

通过此示例,您可以看到,根据您希望代码执行的操作,您可能会遇到问题。如果您希望test2表现得像test1并且忘记使用var关键字,那么当您期望someVariable initialized时,您会感到困惑,而是test2

但您也可以故意不使用 var 关键字,因为您希望test2更新父变量。因此,正确使用 var 关键字非常重要。

初始化变量时不使用var将在全局范围内创建变量。这不是好的做法。如果要在全局范围内设置变量,请手动将它们放在那里。即 window.someVariable = 'initialize';这样,看到您的代码的其他人都知道您故意将其设置为全局变量。