var:两个作用域 全局和局部 没有块元素的概念 局部:函数内部才叫局部
区别1
let和const新增了一个块级作用域 {作用域空间}
let和const只能在作用域空间生效
if(true){
var x=20
}
console.log(x)//20
if(true){
let x=20
const y=20
}
// console.log(x)//报错
console.log(y)//报错
深度理解
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</body>
var lis=document.getElementsByTagName("li")
for(var n=0;n<lis.length;n++){ //全局中的n=4
lis[n].onclick=function(){
console.log(n)//4
// 这个n是在循环中定义的,并且这个循环并没有在函数内部,所以这个n定义的是全局变量的n,
// 当循环结束之后,全局中的n=4,当触发事件时这个n已经循环完成了,
// 他拿的就是全局中的n=4,所以每次都是4
}
}
// let const 和var相比之下存在块局作用域 {作用域空间}
let lis=document.getElementsByTagName("li")
for(let n=0;n<lis.length;n++){
lis[n].onclick=function(){
console.log(n)//0,1,2,3
// 每次循环都是一个花括号,
// 每一个花括号都是一个独立的块级作用域,
// 每一个n都在自己独立的作用域中生效
// 第一次n=0进来 就是一个独有的作用域,所以n=0
}
}
区别2
var定义变量存在变量的默认提升功能,let和const不存在提升问题
console.log(x)//undefined
var x=20
console.log(y)//报错
let y=20
区别3
var可以重复定义,let和const不允许重复定义
var x=20
var x=30
console.log(x)//可以进行覆盖,30
let y=20
let y=30
console.log(y)//报错,已经被定义过了
区别4
var定义的变量默认挂载到window对象上,let和const不会
var x=20
console.log(window.x)//20
let y=20
console.log(window.y)//undefined
区别5
let和const 存在 暂时性死区问题
只要在作用域中 用let定义了变量,就必须在定义后使用 ,哪怕全局有 也不能用
// var a=20
// if(true){
// a=40
// console.log(a)//40
// var a=30
// }
let a=20
if(true){
a=40
console.log(a)//报错
let a=30
}