第 2 章 let 和 const 命令

let 和 const 命令

1. let 命令

基本用法

  • let 命令用于声明变量,其用法类似于 var,但所声明的变量只在 let 所在的代码块内有效
  • for 循环的计数器很适合使用 let 命令
  • for 循环设置循环变量的那部分是一个父作用域,循环体内部是一个子作用域

不存在变量提升

  • var 命令会发生”变量提升“,即变量可以在声明之前使用,值为 undefined
  • let 命令声明的变量一定要在声明之后使用,否则会报错

暂时性死区

  • 只要块级作用域存在 let 命令,它所绑定的变量就”绑定“这个区域,不再受外部影响

不允许重复声明

  • let 不允许在相同作用域内重复声明同一个变量

2. 块级作用域

为什么需要块级作用域

  • 内层变量可能会覆盖外层变量
  • 用于计数的循环变量泄露为全局变量

ES6 的块级作用域

  • 外层作用域无法读取内层作用域的变量
  • 内层作用域可以定义外层作用域的同名变量
  • 块级作用域使得立即执行匿名函数(IIFE)不再必要

块级作用域与函数声明

  • 块级作用域内声明的函数的处理规则:
    1. 允许在块级作用域内声明函数
    2. 函数声明类似于 var,即会提升到全局作用域或函数作用域的头部
    3. 同时,函数声明还会提升到所在的块级作用域的头部
  • 应该避免在块级作用域内声明函数,确实需要也应该写成函数表达式的形式
  • 块级作用域允许声明函数的规则只在使用大括号的情况下成立,如果没有大括号会报错

do 表达式

  • 块级作用域不返回值
  • do 表达式使得块级作用域可以变为表达式,即可以返回值
    1
    2
    3
    4
    let x = do {
    let t = f();
    t * t + 1;
    }

3. const 命令

基本用法

  • const 声明一个只读的常量,一旦声明,常量的值不能改变
  • const 一旦声明常量,就必须初始化,不能留到以后赋值,否则报错
  • const 的作用域与 let 命令相同,只在声明所在的块级作用域内有效
  • const 命令声明的常量也不会提升,同样存在暂时性死区,只能在声明后使用
  • 使用 const 声明常量也和 let 一样,不可重复声明

本质

  • const 实际上保证的并不是变量的值不得改动,而是变量指向的内存地址不得改动
  • 对于简单类型的数据,值保存在变量指向的内存地址中,因此等同于常量
  • 对于复合类型的数据,变量指向的内存地址保存的只是一个指针,const 只能保证这个指针是固定的

    1
    2
    3
    4
    5
    6
    7
    8
    const foo = {};

    // 为 foo 添加一个属性,可以成功
    foo.prop = 123;
    foo.prop //123

    // 将 foo 指向另一个对象,就会报错
    foo = {}; // TypeError: "foo" is read-only
  • 如果想将对象冻结,应该使用 Object.freeze 方法

    1
    2
    3
    4
    5
    const foo = Object.freeze();

    // 常规模式时,下一行不起作用
    // 严格模式时,该行会报错
    foo.prop = 123;

ES6 声明变量的 6 种方法

  • ES5 只有两种声明变量的方法:使用 var 命令和 function 命令
  • ES6 新增了 let、const、import 和 class 命令

4. 顶层对象的属性

  • 顶层对象在浏览器环境中指的是 window 对象,在 Node 环境中指的是 global 对象,在 ES5 中,顶层对象的属性与全局变量是等价的
  • var 命令和 function 命令声明的全局变量依旧是顶层对象的属性
  • let 命令、const 命令和 class 命令声明的全局变量不属于顶层对象的属性

5. global 对象

  • 提案,在语言标准层面引入 global 作为所有环境下的顶层对象
-------------本文结束 感谢您的阅读-------------
您的支持将鼓励我继续创作!