杂货小铺之ES6+ 🍕 Let
2020-07-03 本文已影响0人
羊驼驼驼驼
es.png
-
let
📖 ES6新增了let命令,用来声明变量
- let声明的全局变量不是全局对象window的属性;
var a = 5;
console.log(window.a); // 5
🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
let a = 5;
console.log(window.a); // undefined
🔎 :
var
声明的全局变量是window的属性,是可以通过window.变量名
的方式访问这些变量,而let
声明的变量不能通过这种方式访问
- 用let定义变量不允许重复声明;
var a = 5;
var a = 6;
console.log(a); // 6
🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
let a = 5;
let a = 6;
console.log(a); // 报错:Uncaught SyntaxError: Identifier 'a' has already been declared
- let声明的变量不存在变量提升;
function foo() {
console.log(a)
var a = 5;
}
foo() // undefined
// 等同于
function foo() {
var a;
console.log(a)
a = 5
}
foo() // undefined
🔎 :
a的调用在声明之前,它的值是undefined
,而不是Uncaught ReferenceError
。实际上因为var会导致变量提升
function foo() {
console.log(a)
let a = 5;
}
foo() // 报错:Uncaught ReferenceError: Cannot access 'a' before initialization
🔎 :
a的调用在声明之前,因为let没有发生变量提升,所以读取a的时候,并没有找到,而是在调用之后才找到let对a的定义,所以会报错
4.let声明的变量具有暂时性死区;
var a = 5;
if(true) {
a = 6;
let a;
}
// 报错:Uncaught ReferenceError: Cannot access 'a' before initialization
🔎 :
上面代码中,存在全局变量a,但是块级作用域内let
又声明了一个局部变量a
,导致后者绑定这个块级作用域,所以在let声明变量前,对a赋值会报错;
如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域,凡是在声明之前使用这些变化,就会报错
function foo(a = b, b = 3) {
console.log(a,b);
}
foo() // 报错:Uncaught ReferenceError: Cannot access 'a' before initialization
// 等号是把等号右边的值赋值给等号左边 代码从左向右执行,b还没有值所以会报错
🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
function foo(a = 2, b = a) {
console.log(a,b);
}
foo() // 2 2
- let 声明的变量拥有块级作用域;
for(var i = 0; i < 3; i++) {
console.log('循环内:' + i); // 0 1 2
}
console.log('循环外:' + i); // 3
🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
for(let i = 0; i < 3; i++) {
console.log('循环内:' + i); // 0 1 2
}
console.log('循环外:' + i); // ReferenceError: i is not defined
if(false) {
var a = 5;
}
console.log(a); // undefined
🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
if(false) {
let a = 5;
}
console.log(a); // 报错 Uncaught ReferenceError: a is not defined
🔎 :
使用let定义的变量,它的作用域是这个代码块内部,外部无法访问
- 思考🧐 怎么输出0、1、2;
for(var i = 0; i < 3; i++) {
setTimeout(function(){
console.log(i); // 3 3 3
})
}
// 解决方案1:闭包
for(let i = 0; i < 3; i++) {
(function(j) {
setTimeout(function() {
console.log(j); // 0 1 2
})
})(i)
}
🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
// 解决方案2:let
for(let i = 0; i < 3; i++) {
setTimeout(function(){
console.log(i); // 0 1 2
})
}
🔎 :
把第二个解决方案粘贴到babel
中:https://www.babeljs.cn/rep 转换成es5的代码,会是什么样呢?
// babel 其实把这段代码转化成了闭包的形式
"use strict"
var _loop = function _loop(i) {
setTimeout(function() {
console.log(i);
})
}
for (var i = 0 i < 3 i++) {
_loop(i);
}