1、背景:
在ES6之前声明一个变量都是用var进行声明,但是由于var声明变量具有变量提升作用,无论是在代码后面声明还是前面声明,又或者声明一个块级作用域中的变量,都会将变量提升,导致容易变成全局变量。
1、执行在后
var a=1 //全局变量,声明和赋值一起
console.log(a)
//打印出1
2、执行在前
console.log(a)
var a=1
//var a 能进行变量提升,将a先声明,运行console.log(a),之后才赋值,所以打印出是undefined
如果想变量只作用在块级作用域,ES6之前使用var都会进行变量提升,因此需要结合使用立即执行函数才能实现方法,相当麻烦。
{
var a=1 //因为变量提升,被提升到作用域外面,无法实现
}
如果使用函数进行包裹,虽然对变量a进行实现块级作用域,但是对于函数x来说又是一个全局变量,多次一举。
function x(){
var a=1
window.jack=function(){
console.log(a)
}
}
最后只能结合立即执行函数来实现。
( function x(){
var a=1
window.jack=function(){
console.log(a)
}
}())
总结:你看看想要实现一个变量只在块级作用域中,需要那么麻烦,因此ES6诞生了let和const。
2、let的使用
{
let a=1
console.log(a) //打印出1
}
//就那么简单实现块级作用域变量,只在这个范围有用
(1)、超过块级作用域使用,报错,无效
{
let a=1
}
console.log(a)
//报错:a is not defined
(2)、未声明先使用,报错
console.log(a)
let a=1
//报错:a is not defined
3、const的使用
和let使用基本差不多,唯一区别是const只有一次赋值机会,而且必须在声明的时候立马赋值
{
const a=1
}
最后总结一下:var、let、const区别
(1)、var是ES5语法,let是ES6语法
(2)、var定义变量是函数作用越(全局变量),let定义变量是块级作用域
(3)、var有变量提升,let没有变量提升
(4)、var可以重复声明,let不能重复声明
(5)、let可以重新赋值,const不能重复赋值
4、经典题目:
(1)
var a=1
function fn(){
console.log (a)
}
a=2
fn()
//打印出来是2
修改成下面
var a=1
function fn(){
console.log (a)
}
fn()
a=2
//打印出来是1
这里主要是涉及一个执行顺序问题,所以打印出什么要看代码执行顺序是怎么样的
(2)
<button id='x'>aa</button>
<script>
// 0、1、2、3、4、5,退出循环是6
for(var i=0;i<6;i++){
function fn(){
console.log(i) //打印出i=6
}
x.onclick=fn
}
</script>
你会疑惑为啥打印不是0、1、2、3、4、5,这里涉及到代码执行时间问题,当我们想执行代码时候i早就变成了6。
<button id='x'>aa</button>
<script>
for(let i=0;i<6;i++){ //用let情况
//i0 i1 i2 i3 i4 i5
//块里面的i=圆括号里面的i值
function fn(){
console.log(i) //打印出i=5
}
x.onclick=fn
}
</script>
这里看出使用var打印出是6,使用let打印出是5,这是因为一个是全局变量,一个是块级作用域。