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 关键字声明的函数不能再全局调用。


目录
相关文章
|
6月前
|
JavaScript 前端开发
ES6 块级作用域
ES6 块级作用域
|
8天前
es6变量声明与解构赋值
ES6的变量声明与解构赋值特性使得代码更加简洁、清晰,提高了开发效率和代码的可读性,在实际开发中被广泛应用。
|
5月前
|
JSON JavaScript 前端开发
ES6 解构赋值详解
ES6是JavaScript语言的一次重大更新,引入了许多新特性和语法改进,其中解构赋值是一个非常实用和灵活的语法特性。它可以让我们从数组或对象中提取值,并赋给对应的变量,让代码变得更加简洁和易读。本文将深入探讨ES6解构赋值的语法、用法及其在实际开发中的应用。
191 58
ES6 解构赋值详解
|
3月前
es6 的解构赋值
【8月更文挑战第22天】
20 3
|
4月前
ES6 解构赋值【详解】
ES6 解构赋值【详解】
27 0
|
JavaScript 前端开发 网络架构
ES6 解构赋值
ES6 解构赋值
85 0
|
6月前
|
小程序
es6学习笔记(二)解构赋值
es6学习笔记(二)解构赋值
|
JavaScript 前端开发 编译器
ES6 —— 严格模式
ES6 —— 严格模式
147 0
|
JavaScript 前端开发
ES6:3000字详解变量的改进和块级作用域
ES6中对变量的声明提供了let和const两个新的关键字,解决了var变量存在的很多问题,并提供了块级作用域的支持,这使得很多场景下变量的行为更加合理...
121 0
ES6:3000字详解变量的改进和块级作用域