1、let
let与var都用于定义变量,区别在于:var定义全局变量,挂载在window对象上;而let定义的变量作用于块级作用域中,没有声明提升。
举例:
{
let a = 'hello';
}
console.log(a); // 打印结果报错:Uncaught ReferenceError: a is not defined
var a = 2;
{
let a = 3;
}
console.log(a); // 打印结果:2
let用于for循环:
1、
for (var i = 0; i < 10; i++) {
console.log('循环体中:' + i);
}
console.log('循环体外:' + i);
结果如下:
2、
for (let i = 0; i < 10; i++) {
console.log('循环体中:' + i); // // 每循环一次,就会在 { } 所在的块级作用域中,重新定义一个新的变量 i
}
console.log('循环体外:' + i);
结果如下:
for循环经典案例:
<html lang="">
<head>
<meta />
<meta />
<meta />
<title>Document</title>
</head>
<body>
<input type="button" value="aa" />
<input type="button" value="bb" />
<input type="button" value="cc" />
<input type="button" value="dd" />
<script>
var myBtn = document.getElementsByTagName('input');
for (var i = 0; i < myBtn.length; i++) {
myBtn[i].onclick = function () {
alert(i);
};
}
</script>
</body>
</html>
结果是不论按那个按钮都会出来4,原因:
for 循环是同步代码,而 onclick 点击事件是异步代码。但我们还没点击时,同步代码已经执行完了,这时 i 已经是4了。
上面代码的效果如下:
var i = 0;
myBtn[0].onclick = function () {
alert(i);
};
i++;
myBtn[1].onclick = function () {
alert(i);
};
i++;
myBtn[2].onclick = function () {
alert(i);
};
i++;
myBtn[3].onclick = function () {
alert(i);
};
i++; // 到这里,i 的值已经是4了。因此,当我们点击按钮时,i的值一直都是4
而解决办法就是把var改为let。这样循环体每次执行都会产生一个 i ,互不影响。
2、const
const用于定义常量 ( 值(内存地址)不能变化的量 ),与let一样具有块级作用域,声明时必须赋值。
const a;//报错
const a=1;//不报错
补充: 如果用 const 声明的是对象,这里的“无法被修改”指的是不能改变内存地址的引用;但对象里的内容是可以被修改的。
举例:
const name = 'qianguyihao';
name = 'vae'; // 因为无法被修改,所以报错:Uncaught TypeError: Assignment to constant variable
const obj = {
name: 'qianguyihao',
age: 28,
};
obj = { name: 'vae' }; // 因为无法被修改,所以报错:Uncaught TypeError: Assignment to constant variable
const obj = {
name: 'qianguyihao',
age: 28,
};
obj.name = 'vae'; // 对象里的 name 属性可以被修改
变量名 obj 是保存在栈内存中的,它代表的是对象的引用地址,它是基本数据类型,无法被修改。
但是 obj 里面的内容是保存在堆内存中的,它是引用数据类型,可以被修改。
3、补充:暂时性死区(DTC)
在使用 let/const 声明变量时,变量需要先声明,再使用(声明语句必须放在使用之前)。这在语法上,称为 “暂时性死区”。
举例:
1、(正常)
const name = 'qianguyihao';
function foo() {
console.log(name);
}
foo(); // 执行函数后,打印结果:"qianguyihao"
2、(报错)
const name = 'qianguyihao';
function foo() {
console.log(name);
const name = 'hello';
}
foo(); // 执行函数后,控制台报错:Uncaught ReferenceError: Cannot access 'name' before initialization
3、
const name = 'qianguyihao';
function foo() {
const name = 'hello';
console.log(name);
}
foo(); // 执行函数后,控制台输出:"hello"
参考链接:
https://blog.csdn.net/wangxinxin1992816/article/details/120194828
https://web.qianguyihao.com/05-JavaScript%E5%9F%BA%E7%A1%80%EF%BC%9AES6%E8%AF%AD%E6%B3%95/04-ES6%EF%BC%9A%E5%8F%98%E9%87%8F%20let%E3%80%81const%20%E5%92%8C%E5%9D%97%E7%BA%A7%E4%BD%9C%E7%94%A8%E5%9F%9F.html#%E6%88%91%E7%9A%84%E5%85%AC%E4%BC%97%E5%8F%B7