var
var 是es6之前的关键字,用于声明常量和变量,用var声明的变量具有 声明提升,也就是可以在变量声明前使用和访问,但是在赋值前是undefined
console.log(a) //不报错但是undefined
var a = 10
对于在块内声明的变量,其提升可以提升到块外,不存在块级作用域
console.log(x)// 不报错但是undefined
{
var x = 10
}
//相当于
var x
console.log(x)
{
x = 10
}
类似的块级还有for循环,例如
var a = 1
for(var a = 2; a < 5 ; a++) {
console.log(a)
}
console.log(a)
可能很多人会误以为结果是2,3,4,1,但是答案其实是2,3,4,5,因为对于for循环而言,用var声明的变量并不存在块级作用域,无论是在for{}块内还是在for()内声明的变量,其声明都会被提升到外部,所以上面的例子相当于
var a
var a =1
for(a = 2; a < 5; a++) {
console.log(a)
}
console.log(a)
let
很多情况下,我们也希望类似这种块内的变量有自己的作用域,就像其他c++,java那样有自己的块级作用域,于是es6引进了let和const关键字,这两个关键字也和var类似用于变量和常量的声明定义,其中let用于变量的声明,const用于常量的声明
let与var的区别有以下几点
1.不再存在声明提升,这时候如果在声明前访问和使用变量,会报错
console.log(a) //Uncaught ReferenceError: a is not defined
let a = 10;
2.不允许重复声明同名变量,只要是用let声明一个变量,如果之前存在一个同名变量,无论之前的变量是用let还是var声明的,都会报错
var a = 10
var a = 20
console.log(a) //不报错,a为20
var a = 10
let a = 2 //报错
let a = 10
let a = 2 //报错
let a = 10
var a = 2 //报错
3.在变量初始化之前使用会报错
console.log(a) //Uncaught ReferenceError: a is not defined
let a = 10//报错
4.let声明的变量存在块级作用域(和第一点挂钩)
let i = 10
for(let i = 1; i<3; i++) {
console.log(i)
}
console.log(i)
// 1,2,10
因为不存在声明提升,块级作用域也就理所当然
5.let声明的全局变量不再是window对象的成员
var y = 10
console.log(y) //10
console.log(window.y) // 10
let y = 10
console.log(y) //10
console.log(window.y) // undefined
const
再来说说const,用于声明和定义常量,和let基本用法相同,但是在声明常量时必须初始化,后续不允许修改常量的值
const a
a = 10 //报错Uncaught SyntaxError: Missing initializer in const declaration
const a = 10
a = 3 //报错Uncaught TypeError: Assignment to constant variable.
但是值得注意的一点是,不能修改的是常量的值,但是,js中对象,函数,数组等都是引用传递,也就是传的是地址,地址不能改变,但是地址指向的内容却是可以改变的
const person = {name:"lisi",age:18 }
person.age = 17
console.log(person.age) //17