一.var声明的变量
var是es5中声明变量的方法,var声明的变量是万金油,他没有确定的类型,他的类型取决于赋值给他的变量的类型(javascrpit中的其中数据类型string,number,null,boolean,undefined,object,symbol)。
var声明的变量存在变量提升的情况。
console.log(a);//undefined
var a=3;
可以发现此时a打印出来的是undefined而不是Uncaught ReferenceError: a is not defined,这是因为,var关键字声明的变量,无论实际声明的位置在何处,都会被视为在函数的顶部,如果声明不在任何的函数内,则视为全局作用域的顶部。
二.let声明的变量
let声明的变量是块级作用域,在了解块级作用域前,得先清楚,在es五中,js只有两种形式的作用域:全局作用域与函数作用域。对于var声明的变量,只有函数才能为它创建新的作用域而像if,for中的代码块,并不能为它创建新的作用域。
var a=1;
if(true){
var a=3;
}else{
var a=5;
}
console.log(a);//a=3
代码量小时,可以凭借自己的小心谨慎的,避免出现重复定义的情况,而当代码量大起来时,使用var定义变量就很可能会出现变量名重名的情况,为了解决这种情况,es6引入let这种声明变量的方法。
let a=1;
if(true){
let a=3;
}else{
let a=5;
}
console.log(a);//a=1
let声明的变量为块级作用域,所谓块级作用域就是用{}包括起来的代码块,let定义的a=3与a=5的部分处在if与else的代码块中,作用域也在此,故此时打印的a值为最上面定义的1。需要注意的是,let声明的变量不能重复定义,也不存在变量提升的现象。
let a=1;
let a=2;//Uncaught SyntaxError: Identifier 'a' has already been declared
console.log(a);
let a=1;//Uncaught ReferenceError: Cannot access 'a' before initialization
三.const声明的变量
const也是es6中出现的声明变量的方法,使用const声明变量时,必须在声明变量时就赋值,不能出现先声明后赋值的情况。
const a;
a=1 //Uncaught SyntaxError: Missing initializer in const declaration
const定义的基本数据类型为常量,不能在通过赋值改变其原始值,否则,会引发报错。
const a=1;
a=2 //Uncaught TypeError: Assignment to constant variable.at let.html:12
但是当const定义的是对象时,可以更改对象的属性,也可以添加对象的属性。
const a={b:3,c:4};
a.d=5;
console.log(a)//{b: 3, c: 4, d: 5}
这是因为在定义基本数据类型的变量时,变量名与变量值都保存在栈中,而在定义对象时,变量名保存在栈中,变量值保存在堆中,栈中还保存者堆的地址,const只能保证堆的地址不变,而不能保证堆里面的内容是否发生改变,所以可以更改对象的属性,也可以添加对象的属性。