JavaScript中的变量声明:var
变量 代表了内存中存储数据的位置。直观地说,它们就是一堆我们可以放入数据的盒子的名字。
要使用变量,我们需要先声明一个变量,然后再为其附上数据。
在Javascript中,变量的声明可以用关键字var
、let
和const
。
ES6语言标准里新引入了let
和const
关键字,但是在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模式。
IIFE (I 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的错误。这里有三个步骤:
- 用
var
声明的变量被提升; - 并在编译时给变量赋值为
undefined
; - 当它执行到
test = 10
,则将更新后的值分配给该变量。
注意:声明是提升的,但赋值不提升 。例如:
console.log(name); // undefined
// 这里有一些代码
name = "乐码范";
console.log(name); // 乐码范
// 这里有一些代码
var name;
变量name
由于提升,该变量在第一个console
之前被处理,但只有声明而不是赋值被提升。因此,其值最初是undefined
。就像将undefined
分配给name
变量一样。在执行中完成实际赋值之后,会将值“乐码范”分配给name
变量。