js学习心得——深入理解let

本文探讨了ES6中let命令带来的块级作用域,通过示例展示其区别于var的关键特性。同时,解释了let的变量提升现象,指出let在创建后未初始化时会导致'初始化前无法访问'的错误,而var的创建和初始化都会提升。总结了let和var的提升规则,强调了暂时死区的概念。

一.块级作用域

先来看段代码

{
  let a=1
}
console.log(a); //出错, not defined
{
  var a=1
}
console.log(a); //1
var myList = document.querySelectorAll('li') 
for( let i=0; i<liList.length; i++){
  myList[i].onclick = function(){
    console.log(i)
  }
}//依次点击会依次输出 1 2 3 4 5 

在ES6之前,js中只存在全局作用域和函数作用域,想要模拟块级作用域一般是采用IIFE的写法,在推出ES6后执行起来便简便许多。上述便是两个简单的例子,说明let 声明的变量的作用域是块级的。

二.let 是否存在变量提升

在此之前,让我们来看几个代码段落

console.log(a);// undefined
var a=1;
console.log(a);// Uncaught ReferenceError: Cannot access 'a' before initialization
let a=1;
console.log(a);//Uncaught ReferenceError: a is not defined

我们可以逐步分析,首先第一段代码,我们明白var关键字存在变量声明提升,等效于如下代码

var a;
console.log(a);// undefined
a=1;

输出undefined合情合理,让我有些疑惑的是后面两段代码。
如果说不存在变量声明提升,那当执行到console.log语句时a应该都是not defined才对,为何变成了Cannot access ‘a’ before initialization(初始化前无法访问“a”)。在查阅文档及博客后,我了解到了一个新的知识点:

要搞清楚提升的本质,需要理解 JS 变量的「创建create、初始化initialize 和赋值assign」
有的地方把创建说成是声明(declare),为了将这个概念与变量声明区别开,我故意不使用声明这个字眼。
有的地方把初始化叫做绑定(binding),但我感觉这个词不如初始化形象。
我们来看看 let 声明的「创建、初始化和赋值」过程

依次分析一下执行步骤
1.找到所有用 let 声明的变量,在环境中「创建」这些变量
2.开始执行代码(注意现在还没有初始化)
3.没有初始化,所以报的错为初始化前无法访问“a”
4.var的创建及初始化过程都被提升,默认为undefined

总的来说

let 的「创建」过程被提升了,但是初始化没有提升。
var 的「创建」和「初始化」都被提升了。
function 的「创建」「初始化」和「赋值」都被提升了。

所谓暂时死区,就是不能在初始化之前,使用变量。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值