杂货小铺之ES6+ 🍕 Let

2020-07-03  本文已影响0人  羊驼驼驼驼
es.png

📖 ES6新增了let命令,用来声明变量

  1. let声明的全局变量不是全局对象window的属性;
  var a = 5;
  console.log(window.a); // 5

  🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻

  let a = 5;
  console.log(window.a); // undefined

🔎 \color{Orange}{Warning}:
var声明的全局变量是window的属性,是可以通过window.变量名的方式访问这些变量,而let声明的变量不能通过这种方式访问

  1. 用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
  1. let声明的变量不存在变量提升;
function foo() {
  console.log(a)
  var a = 5;
}
foo() // undefined

// 等同于

function foo() {
  var a;
  console.log(a)
  a = 5
}
foo() // undefined

🔎 \color{Orange}{Warning}:
a的调用在声明之前,它的值是undefined,而不是Uncaught ReferenceError。实际上因为var会导致变量提升

function foo() {
  console.log(a)
  let a = 5;
}
foo() // 报错:Uncaught ReferenceError: Cannot access 'a' before initialization

🔎 \color{Orange}{Warning}:
a的调用在声明之前,因为let没有发生变量提升,所以读取a的时候,并没有找到,而是在调用之后才找到let对a的定义,所以会报错

4.let声明的变量具有暂时性死区;

var a = 5;
if(true) {
  a = 6;
  let a;
}
// 报错:Uncaught ReferenceError: Cannot access 'a' before initialization

🔎 \color{Orange}{Warning}:
上面代码中,存在全局变量a,但是块级作用域内let又声明了一个局部变量a,导致后者绑定这个块级作用域,所以在let声明变量前,对a赋值会报错;
如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域,凡是在声明之前使用这些变化,就会报错

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
  1. 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

🔎 \color{Orange}{Warning}:
使用let定义的变量,它的作用域是这个代码块内部,外部无法访问

  1. 思考🧐 怎么输出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
  })
}

🔎 \color{Orange}{Warning}:
把第二个解决方案粘贴到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);
}
上一篇下一篇

猜你喜欢

热点阅读