JavaScript中的变量声明:var

2020-11-13大约12分钟

变量 代表了内存中存储数据的位置。直观地说,它们就是一堆我们可以放入数据的盒子的名字。

要使用变量,我们需要先声明一个变量,然后再为其附上数据。

在Javascript中,变量的声明可以用关键字varletconst

在Java和许多其他语言中,变量的声明使用不同的关键字。例如用int来表示整数值,char来表示字符等等。但是在JavaScript中,对于所有类型的数据,无论是整数,十进制,布尔值还是字符串,我们都可以用通用的关键字。

ES6语言标准里新引入了letconst关键字,但是在2015年之前,var是变量声明的唯一选择。在本文中,我们将专门讨论var

var关键字

  • var在Javascript中声明函数作用域或全局作用域变量。
  • 它不会创建“块”作用域。
  • 可以多次声明同一变量。
  • 用var声明的变量可以被提升(hoisted )并用undefined值初始化。

1. 语法

JavaScript变量的命名规范:变量名称只能包含字母,数字或符号$和_,并且第一个字符不得为数字。

下面例子里,分别用var声明了三个分别是数值、字符串和函数类型的对象:

var x = 5;
console.log('value of x is: ', x); // value of x is: 5

var str = "I am a string";
console.log(str);  // I am a string

var myFunction = function() {
   console.log('hey');
}
console.log(myFunction);  // ƒ () {console.log('hey');}

2. 作用域(Scope)

var可以声明函数作用域(function-scoped)或全局作用域(globally-scoped)变量,但无法创建块作用域。

全局作用域

var value = 10;
function logger() {
  console.log(value); //10
}
console.log(value); //10

value变量位于全局作用域内,因此我们可以在该范围内的任何位置访问该变量,无论它在函数内部还是在10000行之后。

函数作用域

function mood() {
  var happy = true;
  console.log(happy);  // true
}
console.log(happy);  // ReferenceError: happy is not defined

value变量是在函数作用域内的话,我们只能在函数内部访问它,而不能在函数外面访问。如果在函数外面访问,会产生一个引用错误。

块作用域

var a = 2;
if (a > 1) {
  var name = '乐码范';
}
function logger() {
  console.log(name);
}
logger(); // 乐码范
console.log(name); // 乐码范

在这里,name变量不会创建块作用域,而是像全局作用域中的变量一样随处可见。因此,如果无法实现块作用域,则无法声明任何私有变量。

在2015年之前,使用var是声明变量的唯一选择,然后要获取块作用域时,我们可以使用IIFE模式。

IIFEI mmediately i nvoked f unction e xpressions):立即调用的函数表达式。它描述了可以立即调用的函数表达式,它具有自己的私有变量。例如:

(function() {
  var greeting = "你好,乐码范的用户!";
  console.log(greeting); // 你好,乐码范的用户!
})();

在此语法中,将块代码用函数包括起来,然后立即使用()来调用函数。

然后,我们再用这个方式改造一下前面的代码:

var a = 2;
(function() {
  if (a > 1) {
    var name = '乐码范';
  }
})();
console.log(name); // ReferenceError: name is not defined

3. 变量声明和重新初始化

var可以对变量再次声明和初始化,这不会引起JavaScript的任何错误。

var name = '乐码范';
var name = 'lema.fun';
console.log(name); // lema.fun

4. 提升(Hoisting)

在执行任何代码之前,先处理变量声明。因此,在代码中的任何位置声明变量等同于在顶部声明变量。此行为称为“提升”,因为似乎变量声明移到了范围的顶部:函数或全局。

test = 10;
var test;
console.log(test); // 10

使用var,我们可以先给变量赋值,然后再声明该变量。这不会引发JavaScript的错误。这里有三个步骤:

  1. var声明的变量被提升;
  2. 并在编译时给变量赋值为undefined
  3. 当它执行到test = 10,则将更新后的值分配给该变量。

注意:声明是提升的,但赋值不提升 。例如:

console.log(name); // undefined
// 这里有一些代码
name = "乐码范";
console.log(name); // 乐码范
// 这里有一些代码
var name;

变量name由于提升,该变量在第一个console之前被处理,但只有声明而不是赋值被提升。因此,其值最初是undefined。就像将undefined分配给name变量一样。在执行中完成实际赋值之后,会将值“乐码范”分配给name变量。