1. var
- 存在变量提升(也就是变量使用可以在用var定义之前)
function ff() {
// 顶部会声明var a;(就是变量自动提升)
console.log(a);// 可以先打印再定义,但此时打印的a值是 undefind
var a = 1; // a:作用范围是ff
}
ff();
- 在函数中用var声明的变量是局部变量,其他地方用var声明的变量会自动提升为全局变量
var b = 1; // 自动变量类型提升成全局变量
console.log(b) // 1
console.log(window.b) // 1
- 多个变量会自动提升成为唯一的一个变量
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
var lis = document.querySelectorAll('li')
// 多个 (自动提升成一个唯一的i => 012345)
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function() {
alert(i) // 此时无论点击列表的哪一个值,弹出的a值都是5
}
}
</script>
</body>
以上情况的解决方案有3种:
//1. 最近快的方案是将var修改为用let声明i,这样可以避免变量自动提升
//2. 自执行函数(闭包)
(function (n) {
lis[n].onclick = function () {
alert(n)
}
})(i);
//3. // 给元素绑定值
lis[i].id = i;
lis[i].onclick = function () {
alert(this.id);
}
2. let
- let 是块级的。不会变量类型提升成全局唯一的
- let不同块,不唯一
- let遵循变量的就近原则
let n = 99;
if (true) {
let n = 3;
console.log(n); // 3(体现了变量的就近原则)
}
- let 声明的变量属于块级作用域{ }(块级作用域可以理解为一对{}里面)
- 编译期将其解析,不再向上查找
- 在其初始化之前,不能访问该变量: 临时性死区
let n2 = 1;
if (true) {
console.log(n2); // 这里还未声明就打印,会报错
let n2 = 100;
}
3. const
const声明的值不能被二次改变,并且必须一次性赋值
const PI = 3.1415926;
PI = 888; // TypeError: Assignment to constant variable.
console.log(PI);
const可以用于声明引用数据类型,因为其存储的是存放地址,实际地址上对应的数据还是可以修改的
**const obj = {}; // 存储是地址
obj.a = 1;
obj.b = 2;
console.log(obj);**
var、let、const的区别
- var 顶部声明自动提升为【全局】(唯一)
- var 语法上允许多次声明同名变量,后声明的会覆盖以前的值
- let 不会提升为全局,块级作用域(不唯一)
- let 语法上同作用域内不允许多次声明同名变量
- const声明一个只读的变量,声明后,值就不能改变
- const必须初始化