In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
这篇文章主要介绍"怎么理解ES6块级作用域",在日常操作中,相信很多人在怎么理解ES6块级作用域问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"怎么理解ES6块级作用域"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
作用域
作用域指变量所作用的范围,在 Javascript 中有两种作用域:
全局作用域
函数作用域
变量提升
变量提升(Hoisting)被认为是, Javascript 中执行上下文 (特别是创建和执行阶段)工作方式的一种认识。具体表现就是所有通过 var 声明的变量会提升到当前作用域的最前面。
function foo() {
console.log(temp);
}
function bar() {
console.log(temp);
var temp;
}
foo(); // ReferenceError: temp is not defined
bar(); // undefined
可以看到用 var 声明了的并不会报错。因为其实函数 bar 等同于
function bar() {
var temp;
console.log(temp);
}
大多数类 C 语言语法的语言都拥有块级作用域。在一个代码块(括在一对花括号中的一组语句)中定义的所有变量在代码块的外部是不可见的。定义在代码块中的变量在代码块被执行结束后会变释放掉。这是件好事。
糟心的是,尽管 Javascript 的代码貌似支持块级作用域,但实际上 Javascript 并不支持(就是因为有变量提升)。这个混淆之处可能成为错误之源。
所以在 ES6 中规定了 let 和 const 来支持块级作用域。但是,是不是真的提升就不存在了呢,可以看下面暂时性死区这部分。
let
let 可以理解为『更完美的 var』,使用方法很简单;
let foo = 3;
使用方法基本和 var 相同,而且声明的变量只在其块和子块中可用,这点也与 var 相同。 二者之间最主要的区别在于 var 声明的变量的作用域是整个封闭函数。
function foo() {
if(true) {
var temp = 5;
console.log(temp);
}
console.log(temp);
}
function bar() {
if(true) {
let temp = 5;
console.log(temp);
}
console.log(temp);
}
foo(); // 5 和 5
bar(); // 5 和 "ReferenceError: temp is not defined
let 声明的变量的作用域只是外层块,而不是整个外层函数。
我们可以利用这个特性来替代立即执行函数(IIFE)。
// IIFE
(function(){
var temp = xxx;
/*
other code
*/}())
// 块级
{
let temp = xxx;
/*
other code
*/
}
const
const 的用法跟 let 差不多,但是 const 一定要初始化, 不初始化是会报错的。
const temp = 4;// 没有初始化报错
const t; // SyntaxError: Missing initializer in const declaration
const 是块级作用域,const 跟 let 的语义相似,就是用来声明常量的,一旦声明了就不能更改。值得注意的是 const 声明的变量记录的是指针,不可更改的是指针,如果 const 所声明的是对象,对象的内容还是可以修改的。
// 重新赋值声明导致报错
const PI = 3.14;
PI = 3.1415926; // TypeError: Assignment to constant variable.
// 给对象增加属性不会导致 obj 的指针变化,所以不会报错
const obj = { foo: 2 };
obj.bar = 3;
console.log(obj); // {foo: 2, bar: 3}
暂时性死区
使用 let 或 const 声明的变量,在声明没有到达之前,访问该变量都会导致报错,就连一直以为安全的 typeof 也不再安全。
// TDZ1
function foo() { // TDZ 开始
console.log(typeof temp);
let temp = 5; // TDZ 结束
}
foo(); // ReferenceError: temp is not defined
报的错是 ReferenceError,如果使用 var 声明的话,temp 输出应该是 undefined,从 let 声明的变量的块的第一行,到声明变量之间的这个区域被称作暂时性死区(TDZ)。凡是在这个区域使用这些变量都会报错。
// TDZ2
function bar() {
console.log(typeof temp);
}
bar(); // undefined
看到上面两个例子仔细思考有没有觉得想到点什么?
在函数里没有用 let 声明 temp 的时候,temp 是 undefined,讲道理在 let 声明前也应该是 temp,然而 foo 函数却报了错,证明了就算是在未到达 let 声明的地方,但是在用 let 之前已经起到了作用。这是不是说明其实 let 也有提升,只是在 TDZ 使用的时候报错了,而不是 undefined。
事实上,当 JS 引擎检视下面的代码块有变量声明时,对于 var 声明的变量,会将声明提升到函数或全局作用域的顶部,而对 let 或 const 的时候会将声明放在暂时性死区内。任何在暂时性死区内访问变量的企图都会导致"运行时"错误(runtime error)。只有执行到变量的声明语句时,该变量才会从暂时性死区内被移除并可以安全使用。
禁止重复声明
在同一个块内,let 和 const 不能声明相同的标识符。禁止的情况包括:
let 或 const 和 let 或 const
var 和 let 或者 const
函数参数与 let 或 const
// let 和 let
let foo = 1;
let foo = 2;
// let 和 const
let foo = 1;
const foo = 1;
// var 与 let
var foo = 1;
let foo = 1;
// 函数参数与 let
function bar(foo) {
let foo = 1;
}
以上情况都是会报 SyntaxError。但是在嵌套的作用域内使用 let 声明同一变量是被允许的。
var foo = 1;
{
// 不会报错
let = 2;
// other code
}
同时因为是 let 和 const 是块级作用域,声明的变量在当前块使用完之后就会被释放,所以就算使用相同的标识符也不会覆盖外部作用域的变量, 而 var 是会覆盖外部作用域的变量的。
function foo() {
var bar = 1;
{
let bar = 2;
}
console.log(bar);
}
function zoo() {
var bar = 1;
{
var bar = 2;
}
console.log(bar);
}
foo(); // 1
zoo(); // 2
最佳实践
在 ES6 的发展阶段,被广泛认可的变量声明方式是:默认情况下应当使用 let 而不是 var 。对于多数 JS 开发者来说, let 的行为方式正是 var 本应有的方式,因此直接用 let替代 var 更符合逻辑。在这种情况下,你应当对需要受到保护的变量使用 const。
在默认情况下使用 const ,而只在你知道变量值需要被更改的情况下才使用 let 。这在代码中能确保基本层次的不可变性,有助于防止某些类型的错误。
思考题
两个思考题,我会把答案放在评论中。请点击原文链接去看答案
// 思考题 1
switch (x) {
case 0:
let foo;
break;
case 1:
let foo; // TypeError for redeclaration.
break;
}
// 思考题 2
function bar(){
var foo = 1;
if (true) {
let foo = (foo + 2);
}
}
bar();到此,关于"怎么理解ES6块级作用域"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.