块级作用域

154 阅读2分钟

这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

前言

ECMAScript 6.0 简称ES6 , 是 JavaScript 语言的新一代的标准,于在 2015 年 6 月发布,正式名称就是《ECMAScript 2015 标准》。一般情况,泛指, 5.1版以后的标准,涵盖了 ES2015、ES2016、ES2017、ES2018、ES2019、ES2020、ES2021 等等

我们一起来学习吧。

ES5以前的作用域

在 ES5 只有全局作用域函数作用域,没有块级作用域, 还有一种特殊的 eval 作用域。 函数嵌套就会产生作用域链,内层的作用域的变量会覆盖外层的作用域的变量。

  1. 全局作用域
    代码中的任何地方都能访问,其生命周期伴随着程序的生命周期。
  2. 函数作用域
    函数内部定义的变量,只能在函数内部被访问。函数执行结束之后,被销毁。

不少问题:

  1. 覆盖外层变量
var name = "小明";
console.log(name); // 小明
if (true) {
    var name = "小红";
    console.log(name); // 小红
}
console.log(name); //  小红

一个if语句之后,额, name被很隐蔽的修改了。 var name = "小红" 本只想在 if代码端内生效,结果修改了外面的变量。苦恼。

  1. 无意产升额外变量
for(var i=0; i< 5; i++){
    console.log(i);
}
console.log(i);  // 5

i无意间就成为了全局变量。 在函数里遍历,同样存在相同的问题。

ES6块级作用域

从表象来看, let和const 新增了块级作用域, 让其只在 {}代码块内生效。

let name = "小红";并没有影响到外面申明的name变量。

var name = "小明";
console.log(name); // 小明
if (true) {
    let name = "小红";
    console.log(name); // 小红
}
console.log(name); //  小明

let i=0申明的i遍历完毕后,i就不能被访问了。

for(let i=0; i< 5; i++){
    console.log(i);
}
console.log(i);  
// Uncaught ReferenceError: i is not defined

这里就有一些怪异了,命名感觉没有 {}包裹, 咋就成了块级作用域呢。 这是因为 for语法的特殊性,单独的文章讲解。

暂时性死区

块级作用域内letconst申明,不再受外部的影响。会导在块级作用域内申明之前不可以被访问, 这就是暂时性死区。

var a = 10; 
// let a = 10;
// const a = 10
function log(){
    console.log(a);
    let a = {};
}
log();

image.png

这导致了的typeof也不是百分百安全了

var a = 10; 
function log(){
    console.log(typeof a);
    let a = {};
}
log();
// VM4976:5 Uncaught ReferenceError: Cannot access 'a' before initialization

let和const本质产生了一个词法环境,于此对应的还有一个变量环境。

变量的查询,是先从词法环境查,没有到变量环境,依次类推,最后到全局环境。

ES5怎么实现块级作用域呢? 你猜,当然是IIFE.

小结

今天你收获了吗?