1.let作用域局限于当前代码块
代码1:
{
var str1 = '张三'
console.log(str1)//张三
let str = '李四'
console.log(str)//李四
}
console.log(str1)//张三
console.log(str)// Uncaught ReferenceError:str is not defined
let作用域仅限于当前代码块,而var的作用域是全局的
2.let作用域不会被提升
代码2:
{
console.log(str)//undefined
var str = '小三'
console.log(str1)// Uncaught ReferenceError:str1 is not defined
let str1 = '小四'
}
let作用域不会被提升,而var作用域会被提升
代码2相当于:
{
var str
console.log(str)
str = '小三'
console.log(str1)
let str1 = '小四'
}
所以str会从控制台打印出undefined而不是报错str未定义
3.let不能被重复定义
代码3:
var str1 = '小小'
var str1 = '小二‘
console.log(str1)//小二
let str = '小小'
let str = '小二'//Uncaught SyntaxError: Identifier 'str' has already been declared
var重复定义前面的会覆盖后面,而let则不行,会报语法错误,str已经被声明
4.let父子作用域
代码4:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>learn</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
var btns = document.querySelectorAll('button')
for(var i=0;i<btns.length;i++){
btns[i].onclick = function(){
alert('点击第'+i+'按钮')
}
}
</script>
</body>
</html>
此时弹出的都是点击的第5个按钮,因为此时的i取的是全局的
代码4改变一下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>learn</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
var btns = document.querySelectorAll('button')
for(var i=0;i<btns.length;i++){
(function(i){
btns[i].onclick = function(){
alert('点击第'+i+'按钮')
}
})(i)
}
</script>
</body>
</html>
此时通过闭包的方式传一个参数进去,弹出来的会是对应的下标0,1,2,3,4
代码5:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>learn</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
let btns = document.querySelectorAll('button')
for(let i=0;i<btns.length;i++){
btns[i].onclick = function(){
alert('点击第'+i+'按钮')
}
}
</script>
</body>
</html>
用let此时会依次打印下标,因为alert里面的i的父是btns[i]这个i,所以此时会依次打印,因为此时不想var定义的走全局
var和let有这4点区别,最后一点一定要注意,可能有点不好理解,自己敲一下代码就明白了。