跳至主要內容

let

GuangBo...大约 4 分钟

提示

从上一节可以知道,使用var声明变量的方式弊端很多,因此ES6增加了两种新的声明方式:let和const。在这一节中,我们先来介绍一下let。

let简介

在ES6中,我们可以使用let来声明一个变量。虽然let和var都可以用来定义变量,但是let有以下4个非常重要的特点。


1.只在代码块中有效

使用let 声明的变量,只在代码块之内有效,即只在块级作用域之内有效

示例1

  if (true) {
      let title = '海贼王'
    }
    console.log(title)

分析

使用let声明的变量只在其所在代码块之内有效,在代码块之外访问会报错。

示例2

  let title = '火影忍者'
    if (true) {
      let title = '海贼王'
      console.log(title)
    }
    console.log(title)

分析

在这个例子中,如果两个变量都使用var来声明,则最终两个console.log0都会输出“海贼王”。从这个例子中也可以看出,使用let来代巷var,可以避免这种内层变量覆盖外层变量的不合理情况。


2.同一代码块中,不允许重复声明

使用let声明的变量,在其所在的代码块中是不允许重复声明的。

示例

 if (true) {
      let title = '火影忍者'
      let title = '海贼王'
      console.log(title)
    }

分析

虽然在同一代码块中,变量不允许被let重复声明,但是这个变量却可以被重新赋值。要注意,声明与赋值是两码事。请看下面的代码。

 if (true) {
      let title = '火影忍者'
      title = '海贼王'
      console.log(title)    // 海贼王
    }

3.不存在变量提升

用let声明变量不像用var声明变量那样会出现变量提升的现象。因此,用let声明的变量只能在声明后使用,如果在声明之前使用,就会报错。

示例: 变量

console.log(title);
let title = '火影忍者';

示例: 函数

console.log(fn)
let fn = function () {
  console.log('火影忍者')
}

4.不会成为window的属性

在ES6之前,在全局作用域中,使用var声明的变量会成为window对象的属性。但是在ES6的全局作用域中,使用let声明的变量不会成为window对象的属性。

示例:ES5中的var

var a = 2077
var fn = function () {
  console.log(2077)
}
console.log(window.a)
window.fn()

示例: ES6中的let

let a = 2077
let fn = function () {
  console.log(2077)
}
console.log(window.a)
window.fn()

let的用途

使用var来定义变量可能引发的一个不合理情况,就是用来计数的循环变量泄露为全局变量.我们先来看一个例子。

示例

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script>
      window.onload = function () {
        var oBtn = document.getElementsByTagName('input')
        for (var i = 0; i < oBtn.length; i++) {
          oBtn[i].onclick = function () {
            console.log(i + 1)
          }
        }
      }
    </script>
  </head>

  <body>
    <input type="button" value="按钮1" />
    <input type="button" value="按钮2" />
    <input type="button" value="按钮3" />
    <input type="button" value="按钮4" />
    <input type="button" value="按钮5" />
  </body>
</html>
图2-1
图2-1

分析

闭包这种方式比较生涩难懂,也不直观。在ES6中,我们可以使用let巧妙地解决这个问题。

示例: 使用let

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script>
      window.onload = function () {
        var oBtn = document.getElementsByTagName('input')
        for (let i = 0; i < oBtn.length; i++) {
          oBtn[i].onclick = function () {
            console.log(i + 1)
          }
        }
      }
    </script>
  </head>

  <body>
    <input type="button" value="按钮1" />
    <input type="button" value="按钮2" />
    <input type="button" value="按钮3" />
    <input type="button" value="按钮4" />
    <input type="button" value="按钮5" />
  </body>
</html>
图2-2
图2-2

分析

由于let声明的变量拥有块级作用域,用来计数的for循环变量(也就是i)不会泄露为全局变量,从而能避免被覆盖。这是一个非常常见而重要的场景,小伙伴们要重点掌握。

上次编辑于:
贡献者: shaoguangbo
评论
  • 按正序
  • 按倒序
  • 按热度