ES6-let-难点

输出3个10 :

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>let-var</title>
</head>
<body>

	<script>

		var a = [];
		for (var i = 0; i < 10; i++) {
			a[i] = function () {
				console.log(i);
			};
		}
		a[1](); // 10
		a[2](); // 10
				
		a[9](); // 10
	</script>
</body>
</html>

原因:var是全局的

	<script>

		var a =10
		var a =12
		var a =11
		console.log(a)//11

	</script>

上述的等价于:var变量提升

	<script>

		var a = [];
		var i = 0
			a[i] = function () {
				console.log(i);
			};
		var i = 1
			a[i] = function () {
				console.log(i);
			};
		var i = 2
			a[i] = function () {
				console.log(i);
			};
		var i = 3
			a[i] = function () {
				console.log(i);
			};
		var i = 4
			a[i] = function () {
				console.log(i);
			};
		var i = 5
			a[i] = function () {
				console.log(i);
			};
		var i = 6
			a[i] = function () {
				console.log(i);
			};
		var i = 7
			a[i] = function () {
				console.log(i);
			};
		var i = 8
			a[i] = function () {
				console.log(i);
			};
		var i = 9
			a[i] = function () {
				console.log(i);//i是全局的i
			};
		var i = 10
			a[i] = function () {
				console.log(i);
			};
		
			console.log(i);//10

		
		a[1](); // 10
		a[2](); // 10
				
		a[9](); // 10
	</script>

let-声明的变量仅在块级作用域内有效

	<script>
		var a = [];
		for (let i = 0; i < 10; i++) {
			a[i] = function () {
				console.log(i);
			};
		}
		a[1]()//1
		a[6](); // 6
	</script>

等价于:

	<script>
		var a = [];
		{let i = 0 
			{
				a[i] = function () {
					console.log(i);//只是当前的i
				};
			}
		}
		{let i = 1 
			{
				a[i] = function () {
					console.log(i);
				};
			}
		}
		{let i = 2
			{
				a[i] = function () {
					console.log(i);
				};
			}
		}
		a[1]()//1
		a[2](); // 2
	</script>

for循环有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域


<script>
    for (let i = 0; i < 3; i++) {
 	 	let i = '33';
  		console.log(i);
	}
	 33
	// 33
	// 33	
</script>

代码块内,使用let命令声明变量之前,该变量都是不可用的{}内前面就算使用了var声明该变量也是不可以使用的。这在语法上,称为“暂时性死区”temporal dead zone,简称 TDZ)——前面不可以使用该变量作为全局变量。变量使用let命令声明,所以在声明之前,都属于x的“死区”,只要用到该变量就会报错。

	<script>
		var i=1
	{	console.log(i)
		let i=12}
		
	</script>

 变量使用let命令声明,所以在声明之前,都属于变量的“死区”,只要用到该变量就会报错。但是变量不使用let声明,反而不会报错

	<script>		

		if (true) {//代码块
					// TDZ开始——使用变量前且在代码块内就会出现TDZ暂时性死区
				tmp = 'abc'; // ReferenceError
				console.log(tmp); // ReferenceError
                let tmp; // TDZ结束
			
		}
		
	</script>
<script>
		
		if (true) {//代码块	
                let tmp; // TDZ结束
				console.log(tmp); // undefined--没有赋值
		}
	</script>
	<script>
		
		if (true) {//代码块
					// TDZ开始——使用变量前且在代码块内就会出现TDZ暂时性死区
				
				let tmp; // TDZ结束
				tmp = 123;
				 console.log(tmp); // 123
		}
		
	</script>

暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

        函数f()执行后,输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。

<script>
var tmp = new Date();
function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}
f(); // undefined
</script>

外层代码块不受内层代码块的影响

function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}

ES6 允许块级作用域的任意嵌套,上面代码使用了一个五层的块级作用域,每一层都是一个单独的作用域。第四层作用域无法读取第五层作用域的内部变量。 

<script>
{{{{
  {let insane = 'Hello World'}
  console.log(insane); // 报错//不在同一个块域内--变量不行
}}}};
</script>

内层作用域可以定义外层作用域的同名变量

<script>
	{{{{
  let insane = 'Hello World';
  {let insane = 'Hello World';}
}}}};
</script>

ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。

  1. 允许在块级作用域内声明函数。
  2. 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
  3. 同时,函数声明还会提升到所在的块级作用域的头部。

块级作用域内部,优先使用函数表达式,而不是函数声明 ,ES6 的块级作用域必须有大括号小括号不算,ES6 的块级作用域必须有大括号,不存在块级作用域,而let只能出现在当前作用域的顶层

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值