块作用域(let const 块作用域函数)

块级作用域

ES6 之前创建"块级作用域"

在没有出现 let const 之前,可以利用函数来实现“块级作用域”,防止某些变量暴露到全局去:

  1. 声明函数创建块级作用域
var a = 23;
function createBlock(){
	var a = 24;
	console.log(a); // 24
}
console.log(a); // 23
  1. 立即执行函数创建块级作用域
var a = 23;
(function createBlock(){
	var a = 24;
	console.log(a); // 24
})()
console.log(a) // 23

ES6 创建块级作用域

1. let 声明
var a = 23;
{
	let a = 24;
	console.log(a); // 24
}
console.log(a); // 23

从上面的例子可以看到,let 把变量 a 绑定到了 { … } 。var a 的值没有被 let a 覆盖,可以看出两个 a 分别处于两个不同的作用域。此时的 { … } 是一个块级作用域。

  • 暂时性死区
	console.log(a); // undefined
	console.log(b); // ReferenceError
	var a;
	let b;

提前访问 b 会报一个 “无法在初始化之前访问 b” 的错误。在 b 声明之前是不能访问 b 的,只能在它声明之后访问。

  • 提前访问 b 和访问未声明的变量,typeof 的结果是不同的:
{
	if(typeof a == 'undefined') console.log('a未声明,访问为undefined');
	if(typeof b == 'undefined') console.log('执行吗?'); // ReferenceError
	let b;
}
  • let 和 for 循环组合

初学 JavaScript 的时候我写过类似下面这样的代码。为了保存 for 循环 i 的值,并对 i 进行操作,当时没有了解作用域的知识,所以结果并没有按照我想的那样进行。上面这段代码中 console.log(i) 只是对 i 进行了引用,没有赋值,并且所有 i 指向的都是同一个作用域下的 i,所以最后打印的结果都是循环结束后的值 i 。

var a = [];
for(var i = 0; i < 5; i++){
	a[i] = function consoleNum(){
	 	      return console.log(i);
	 	   }
}
a[0](); // 5
a[1](); // 5
a[2](); // 5
  • 可以用立即执行函数创建块级作用域并把当时的 i 值传进去并保存在块级作用域解决。但有了 let 之后代码可以更加清晰,看如下代码:
var a = [];
for(let i = 0; i < 5; i ++){
	a[i] = function consoleNum(){
	 	   	 return console.log(i);
	 		}
}
a[0](); // 0
a[1](); // 1
a[2](); // 2

console.log(i) 中的 i 指向的都是 let 绑定的不同的作用域,结果能达到预期,比立即执行函数简洁。

2. const 声明
  • const 声明和 let 一样可以创建块级作用域变量,只是 const 创建的变量的值不能修改。任何尝试修改都会报错。并且在作用域外是访问不到的。
if(true){
	var a = 24;
	const b = 2019;
	a = 25; // 正常 
	b = 2020; // 报错
}
  • const 是对赋值的变量限制不可更改,而不是变量的值被限制。如果 const 的值是对象或数组等复杂数据类型,值仍然是可以修改的。
const a = [1,2,3];
a.push(4); // [1,2,3,4]
a = 24; // TypeError
3. 块作用域函数

ES 6 有了在块内声明的函数,它的作用域在这个块以内。

{
	fn(); // '24'
	function fn(){
		console.log('24');
	}
}
fn(); // ReferenceError

从上面这个例子可以看出两点:

  • fn 函数只在块级作用域内有效。
  • fn 是有提升的,和 let 不一样,没有 let 的暂时性死区。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值