let
1.let在同一作用域下不可重复声明
function test(a) {
let a = 10;
}
test();
报错
function test(a) {
{
let a = 10;
}
console.log(a);
}
test();
返回undefined
function test(a) {
{
let a = 10;
console.log(a);
}
}
test();
返回10
2.let 不会提升 产生一个暂时性死区
console.log(a);
let a = 10;
报错
function test(x = y, y = 2) {
console.log(x, y);
}
test();
修改
function test(x = 2, y = 2) {
console.log(x, y);
}
test();
console.log(typeof a);
let a;
3.let 只能在当前的作用域下生效
{
let a = 2;
}
console.log(a);
if (1) {
let a = 2;
}
console.log(a);
for (; 1; ) {
let a = 2;
break;
}
console.log(a);
for循环小括号里也是块级作用域
而且与大括号里的块级作用域不是一个
for (let i = 0; i < 10; i++) {}
console.log(i);
这里有一个大多数人都可能会错的题
你们觉得最后输出的是什么呢 会是10个10吗
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function () {
console.log(i);
};
}
for (var i = 0; i < 10; i++) {
arr[i]();
}
答案是0-9
第一次循环确实是没有执行 数组中每一个函数确实是输出此时的i为10
但是第二次循环时 重新给i赋值并执行函数 所以是0-9
for (var i = 0; i < 10; i++) {
i = 'a';
console.log(i);
}
它的执行可以分解为
var i = 0;
for (; i < 10; ) {
i = 'a';
console.log(i);
i++;
}
此时i++ = Number( 'a' + 1) = NaN 不小于10 所以就打印一个'a'
for (var i = 0; i < 10; i++) {
var i = 'a';
console.log(i);
}
for (let i = 0; i < 10; i++) {
i = 'a';
console.log(i);
}
for (let i = 0; i < 10; i++) {
var i = 'a';
console.log(i);
}
for (let i = 0; i < 10; i++) {}
console.log(i);
for (let i = 0; i < 10; i++) {
let i = 'a';
console.log(i);
}
所以for小括号中的作用域与大括号中的作用域不是一个作用域
相当于下面这种情况
if (1) {
let i = 0;
{
let i = 'a';
console.log(i);
}
}
如果内部没有定义就向上寻找执行上下文 如果内部有就使用内部的
但是使用var 定义时会有变量提升 可以向上提升到每个块级作用域
if (1) {
let i = 0;
{
var i = 'a';
console.log(i);
}
}
相当于;
if (1) {
var i;
let i = 0;
{
i = 'a';
console.log(i);
}
}
let 是不允许重新赋值的 这里相当于重新对i进行赋值 所以报错
if (1) {
let i = 0;
{
i = 10;
console.log(i);
}
console.log(i);
}
if (1) {
let i = 0;
{
let i = 10;
console.log(i);
}
console.log(i);
}
不建议在块级作用域中使用函数声明的方式声明函数 建议使用函数表达式的方式声明函数
不建议
try {
function test() {}
} catch (error) {}
建议
try {
var test1 = function test() {};
} catch (error) {}
块级作用域没有返回值
块级作用域等于匿名函数的立即调用吗 (×)
总结
1.let在同一作用域下不可重复声明
2.let不会提升 会产生一个暂时性死区
3.let只能在当前的作用域下生效