在本地范围初始化JavaScript变量

时间:2013-02-27 20:40:47

标签: javascript scope

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

如果在声明变量之前写入var会将变量分配给本地范围,那么在初始化变量以使其保持在本地范围内时,是否有必要稍后编写var?例如:

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

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

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

4 个答案:

答案 0 :(得分:3)

var something = "Initial value."

这意味着:“在本地范围内创建一个变量并为其赋予初始值”。本地范围表示使用此语句的函数。

something = "New value."

这意味着:“在最近的范围内找到变量'某事',并为其指定一个新值”。 如果您在没有使用第一个语句的情况下使用第二个语句,则语句将在逐渐变大的范围中查找something的任何定义(包含您的函数的函数,如果存在,包含该函数的函数等,直到达到全球范围)。如果它找到了什么,它将分配给一个已经存在的变量。如果没有找到任何内容,它将创建一个具有该名称的全局变量。

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

答案 1 :(得分:2)

这些是相同的:

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'。通过在函数中引用x前面的var,它将局部范围应用于变量。一旦函数完成,变量的原始范围就会恢复(或者重新范围丢失,如果你想以这种方式查看它)。感谢@zzzzBov指出这一点。

希望这有帮助。

答案 2 :(得分:2)

  

我的理解是,在变量声明之前写入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

  

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

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

答案 3 :(得分:0)

如果使用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';这样,看到你代码的任何其他人都知道你故意把它变成一个全局变量。