ES 6 块级作用域

简介: ES 6 块级作用域

块级作用域

1. let 关键字与 var 关键字的区别

ECMAScript 6 新增了 let 关键字用于声明变量,该变量只能在指定的代码块内有效。

(1)块级作用域与函数作用域

如下代码所示:

{
    let a = 100;//块级作用域
    var b = 1 00;//函数作用域
}
console.log(b)//100
console.log(a)//a is not defined

显而易见,结果是使用 let 声明的变量报错,var 声明的变量输出正确的值。


(2)暂时性死区(不存在声明提前)

ECMAScript 6标准明确规定,如果在一个代码块中使用 let 或 const 声明变量或常量时,当前代码块中对这些声明的变量或常量形成了一个封闭的作用域。


在这个代码块中,在使用 let 或 const 声明之前,该变量或常量都是不可用的。这种情况,在语法上被称为“暂时性死区”( Ternporal Dead Zone,简称为TDZ)。


使用 var 关键字声明变量时会出现声明提前的情况,就是变量在声明之前被访问,其值为undefined。


但 let 关键字不允许变量声明提前。


如下代码所示:

console.log(m);//undefined
var m = 100;
// var 关键字声明允许声明提前
console.log(v);
let v = 100;//ReferenceError: Cannot access 'v' before initialization
//let 关键字声明不允许声明提前

(3)let 不允许重复声明

let 关键字与 const 关键字一样,定义的变量不允许重复声明。

示例代码如下:

// 使用关键字var允许重复声明
var v = 100;
console.log(v);
var v = 1000;//重复声明 - 不报错
console.log(v);
/*
// 使用关键字 let 不允许重复声明
let m = 100;
console.log(m);
let m = 1000;//重复声明 - 报错
console.log(m);//SyntaxError: Identifier 'm' has already been declared
*/
// 使用关键字 let定义变量允许重新赋值
let m = 100;
console.log(m);
m = 1000;//重复赋值
console.log(m);//1000

值的注意的是:使用关键字 let 虽然不允许重复声明,但可以重新赋值。

(4)与函数的区别

// 1.使用var允许声明提前
/*
var v = 100;
function fn(){
    console.log(v);//undefined
    var v = 1000;
    console.log(v);//1000
}
fn();
*/
// 2.使用let不允许声明提前
/*
let v = 100;
function fn(){
    // 函数作用域封闭 - 全局作用域中的变量与当前函数作用域无关
    console.log(v);//ReferenceError: Cannot access 'v' before initialization
    let v = 1000;
    console.log(v);//1000
}
fn();
*/
//3.函数作用域内
let v = 100;//全局变量
console.log(v);//100
// 自调函数
(function(){
    let v ;
    // 函数作用域
    console.log(v);//undefined
})();
if (true){
    console.log(v);//100
}

(5)与函数参数的区别

/*// 在ES6中函数的参数相当于使用let关键字定义的局部变量
function fn(a) {
    let a = 1000;
    console.log(a);//SyntaxError: Identifier 'a' has already been declared
}
fn(100);*/
/*function fn(a) {
    let a = 1000;
    console.log(a);//SyntaxError: Identifier 'a' has already been declared
}
fn(100);*/
function fn(a) {
    a = 1000;//允许重新赋值
    console.log(a);//100
}
fn(100);

在 ES 6 中函数的参数相当于使用 let 关键字定义的局部变量

2.为什么需要块级作用域?

在循环体中用于技术的变量泄露为全局变量

如下示例代码所示:

 /*
// 全局作用域
for (var i=0;i<10;i++){
    console.log(i);
}
console.log(i);//10 用于计数的变量泄露为全局变量
*/
// 块级作用域
for (let i=0;i<10;i++){
    console.log(i);
}
console.log(i);//ReferenceError: i is not defined

上述示例代码中,关键字 var 定义的变量 i 只用于控制循环体的执行。当循环体执行结束后,变量 i 并没有释放,而是作为全局变量存在。而关键字 let 定义的变量 i 只用于控制循环体的执行。当循环体执行结束后,变量 i 释放。

经典面试题(循环体与数组的关系 )

/*
var arr = [];
for (var i=0;i<10;i++){
    arr[i]=function () {
        return i;
    };
}
console.log(arr[9]());//10 因为var关键字定义的变量i为全局变量
*/
var arr = [];
for (let i=0;i<10;i++){
    arr[i]=function () {
        return i;
    };
}
console.log(arr[6]());//6 因为let关键字定义的变量i为块级作用域

上述示例代码 var 关键字定义的i变量为全局变量,所有最后return的i的值都为10。

解析图如下:

3.块级作用域的函数声明

ECMAScript 5标准规定函数的声明只能在全局作用域和函数作用域中,不能在块级作用域中声明。

/*
if (true){
    // 块级作用域
   var fun = function(){
        console.log('this is function')
    }
}
// 全局作用域调用
fun();
*/
// let 关键字声明函数
if (true){
    // 块级作用域
    let fun = function(){
        console.log('this is function');
    }
}
// 全局作用域调用
fun();//ReferenceError: fun is not defined

使用var关键字声明的函数可以在全局调用,但是使用let 关键字声明的函数不能再全局调用。


目录
打赏
0
0
0
0
2
分享
相关文章
Python爬虫实战:抓取网站数据并生成报表
本文将介绍如何使用Python编写简单而高效的网络爬虫,从指定的网站上抓取数据,并利用数据分析库生成可视化报表。通过学习本文内容,读者将能够掌握基本的爬虫技术和数据处理方法,为日后开发更复杂的数据采集与分析工具打下坚实基础。
java.security.InvalidKeyException: Illegal key size。
java.security.InvalidKeyException: Illegal key size。
190 0
Linux命令(109)之md5sum
Linux命令(109)之md5sum
210 1
|
11月前
|
高德地图之获取经纬度并且根据获取经纬度渲染到路线规划
高德地图之获取经纬度并且根据获取经纬度渲染到路线规划
258 0
RDS MySQL的SQL问题诊断与调优
本教程为您介绍如何通过控制台在RDS MySQL上创建账号和数据库,通过DMS进行MySQL常见的表创建、索引创建等操作。
C++初阶之一篇文章让你掌握vector(理解和使用)(上)
1.什么是vector? 在C++中,std::vector是标准模板库(STL)中的一种动态数组容器,它可以存储任意类型的元素,并且能够自动调整大小。std::vector提供了许多方便的成员函数,使得对数组的操作更加简单和高效。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问