🌈 不能在同一作用域中重复声明

function test(a) {
  let a = 10;
  console.log(a);
}
test();

// 答案:

// SyntaxError: Identifier 'a' has already been declared

🌈 没有声明提升,声明之前不可用,会产生一个暂时性死区

console.log(a);
let a = 1;

// 答案:

// Uncaught ReferenceError: Cannot access 'a' before initialization

function test() {
	console.log(a);
  let a = 10;
}
test();

// 答案:

// Uncaught ReferenceError: Cannot access 'a' before initialization at test
var a = a;
console.log(a);

// 答案:

// undefined

let b = b;

console.log(b);

// 答案:

// Uncaught ReferenceError: Cannot access 'b' before initialization
var a = 1;
{
	let a = a;
  console.log(a);
}

// 答案:

// Uncaught ReferenceError: Cannot access 'a' before initialization
console.log(typeof a);
let a = 10;

// 答案:

// Uncaught ReferenceError: Cannot access 'a' before initialization
function test(x = y, y = 2) {
	console.log(x, y); // 报错
	// Uncaught ReferenceError: Cannot access 'y' before initialization
}
test();

// 下面可行
function test(x = 1, y = x) {
  console.log(x, y);
}

test();

🌈 只在当前作用域下生效

if (true) {
	let a = 1;
}
console.log(a); // Uncaught ReferenceError: a is not defined
for (;1;) {
	let a = 1;
}
console.log(a); // 不会执行,所以也不会报错
// 因为 上边 for 循环会 死循环
for (var i = 0; i < 10; i++) {
	var i = 'a';
  console.log(i); // a
}
for (let i = 0; i < 10; i++) {
  
}
console.log(i); // Uncaught ReferenceError: i is not defined
for (var i = 0; i < 10; i++) {
  i = 'a';
  console.log(i);
}
// 打印1个a

// 解析:
var i = 0;
for (; i < 10;) {
	i = 'a';
  console.log(i);
  i++;
}

// 1. 第一次循环完毕,i = 'a' 打印 'a',i++ => NaN
// 2. 第二次循环 NaN < 10 不成立,不执行for循环里边代码

🌈 let 本质上是就是为 js 增加了一个块级作用域

for (let i = 0; i < 10; i++) {
  i = 'a';
  console.log(i);
}

// 打印1个a
for (let i = 0; i < 10; i++) {
  let i = 'a';
  console.log(i);
}

// 打印10个a

if (1) {
	let a = 0;
  {
  	let a = 'a';
  }
}

// for循环的let声明相当于for循环内部的父级
// 所以内外不影响
for (let i = 0; i < 10; i++) {
  var i = 'a'; // i被重复定义
  console.log(i);
}

// SyntaxError: Identifier 'i' has already been declared

// for内部的var i为什么报错呢?可以类比成

if (1) {
	let a = 0;
  {
  	var a = 'a';
  }
}

// 而这个var是会有个类似dom冒泡的机制,有变量提升,会变成

if (1) {
  var a = undefined;
	let a = 0;
  {
  	 a = 'a';
  }
}

由于同一作用域下let不允许重复定义变量,所以报错

块级作用域没有返回值

if (1) {
    return '233';
} // 返回不出去

// 如何才能可以有返回值:用do,但是兼容性不好
do {
	return 1;
}