美文网首页
重读 ES6(一)

重读 ES6(一)

作者: 梧桐月明中 | 来源:发表于2021-02-05 15:31 被阅读0次

一、let 和 const 命令

let 命令

  • let 与 var 的区别:let 声明的变量只在 let 命令所在的代码块中有效
  • let 不存在变量提升
  • 因此会有暂时性死区
  • 暂时性死区也意味着 typeof 不再是百分百安全的操作

块级作用域

  • ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景:内层变量可能会覆盖外层变量(if 里的var 变量提升到 if 外);用来计数的循环变量泄露为全局变量。
  • let 使得 es 有了块级作用域
  • 在块级作用域中声明函数,理论和实际:es5 不允许,浏览器不听;es6 允许,规定其行为类似 let,在作用域外不可引用,浏览器不听,为了降低兼容问题,es6 的浏览器让其行为类似 var,会变量提升,但 es6 的其它环境遵守规定。
  • 考虑到环境导致差异太大,应避免在块级作用域中声明函数,如果非要,也应写成函数表达式的形式,而非函数声明。

const 命令

  • const 的作用域与 let 相同
  • es6 声明变量共有 6 种方法:
    es5 的 var function
    es6 的 let const class import

顶层对象

  • 浏览器的 window,Node 的 global,全局作用域定义的变量会成为顶层对象的属性,这不合理
  • 所以 ES6 规定 let const class 定义的全局变量不属于顶层对象的属性,varfunction 为了兼容保持不变
  • 怎样获取顶层对象,浏览器是 window,Node 是 global,浏览器 和 Web Worker 中 self 也指向顶层对象
  • 获取顶层对象的环境差异太大,ES2020 引入 globalThis 作为(指向)顶层对象

二、变量的解构赋值

  • 数组的结构赋值
let [a, b, c] = [0, 1, 2]
a // 0
b // 1
c // 2

let [head, ...tail] = [1, 2, 3, 4]
head // 1
tail // [2, 3, 4]

// 默认值
let [x = true] = []
x // true

// 默认值是 值 === undefined 时触发
let [x = true] = [null]
x // null
  • 对象的解构赋值
// 如果变量名与属性名不一致,要这样写
let { foo: baz } = { foo: 'aaa', bar: 'bbb' }
baz // 'aaa'
foo // error: foo is not defined
  • 类数组对象(比如字符串)的解构赋值
const [a, b, c, d, e] = 'hello'
a // 'h'

let { length: len } = 'hello'
len // 5
  • 数值和布尔值的解构赋值
let { toString: s } = 123
s === Number.prototype.toString // true
  • 解构赋值的规则是,如果等号右边不是对象或数组,就先将其转为数组,nullundefined 无法转为数组,因此对他们解构赋值会报错
let { prop: x } = undefined // TypeError
let { prop: y } = null // TypeError

用途

  • 引入模块的指定方法
  • 函数参数的定义
  • 函数参数的默认值
  • 从函数返回多个值
  • 交换变量的值
  • 提取 JSON 数据
  • 遍历 Map 结构
// 任何部署了 Iterator 接口的对象都可以使用 for...of 循环遍历
// 搭配解构赋值,获取键名和键值更加方便
const map = new Map()
map.set('first', 'hello')
map.set('second', 'world')

for (let [key, value] of map) {
  console.log(key + ' is ' + value)
}
// first is hello
// second is world

三、字符串的扩展

  • 字符的 Unicode 表示法:\u{20BB7}
  • 给字符串添加了 Iterator 接口,使其可以用for...of 遍历
  • 模板字符串
  • 标签模版
  • 标签模版带参数

四、字符串的新增方法

String.fromCodePoint()

  • 可以识别大于\uFFFF 的码点
  • 是对 String.fromCharCode() 的升级
  • 作用与 str.codePointAt() 相反

String.row()

  • 返回一个斜杠被转义的字符串
  • 是专用于模板字符串的标签函数

str.codePointAt()

  • 比较:charCodeAt()
  • 对于32位的 UTF-16 编码的字符,可以正确返回大于 \xFFFF 的值,但长度还是2
  • 要正确识别长度,可使用 for of 或者使用 ... 展开运算

str.normalize()

  • unicode 正规化
  • 合成符号的概念
  • 四个参数
  • 不能识别中文

str.includes str.startsWith str.endsWith

  • 返回布尔值,均支持第二个参数,表示开始检索的位置
  • 原有的 indexOf 用来查看字符串是否包含在另一个字符串之中

str.repeat()

  • 返回一个字符串,是原字符串重复n遍
  • 小数参数会被向下取整
  • 参数是 Infinity 或 负数会报错

str.padStart() str.padEnd()

  • 补全长度
  • 接收两个参数,第一个是长度,第二个是用于补全的字符串
  • 省略第二个参数会用空格来补全

str.trimStart() str.trimEnd()

  • 类似 str.trim(),顾名思义

str.matchAll()

str.replaceAll()

  • 和 replace 一样,返回新字符串,不改变原字符串
  • 第二个参数中的特殊字符串:$& $` $' $n $$

五、正则的扩展

  • 构造函数的扩展,允许 var reg = new RegExp(/xyz/ig, 'i') 形式(即第一个参数是表达式的情况下,允许第二个参数将 flags 覆盖),会等同于 var reg = /xyz/i
  • u 修饰符
    reg.unicode
  • y 修饰符
    reg.sticky
  • s 修饰符
    reg.dotAll
  • reg.source reg.flags
  • 后行断言
  • Unicode 属性类
  • 具名组匹配
  • str.matchAll() 返回的是遍历器 Iterator
    转为数组很简单:
// 法一
[...str.matchAll(regexp)]
// 法二
Array.from(str.match(regexp))

六、数值的扩展

  • 二进制 0b 和八进制 0o 表示
  • Number.isFinite() 是否是有限的,对于非数值,都返回 false
  • Number.isNaN() 只对 NaN 返回 true
  • 而全局函数isFinite()isNaN() 会先把非数值参数转为数值
  • Number.parseInt() Number.parseFloat() 与全局函数无差,是为了让方法回归到模块本身
  • Number.isInteger() 判断是否是整数,对非数值返回 false,精度超出限制会误判
  • Number.EPSILON 极小的常量 Number.EPSILON === Math.pow(2, -52)
  • JS 能表示的整数在 -2^532^53 之间(不含两端),超出这个范围则无法精确表示这个值
    Number.MAX_SAFE_INTEGER 最大安全整数,等于 2^53 - 1
    Number.MIN_SAFE_INTEGER 最小安全整数,等于 -2^53 + 1
    Number.isSafeInteger() 判断整数是否在这个范围内,非整数返回 false
  • Math 新增 17 个静态方法
  • 指数运算符 2 ** 3 === 8
  • BigInt:第八种数据类型,数值加后缀 n 表示
    前七种:Undefined Null Boolean String Number Object Symbol

相关文章

网友评论

      本文标题:重读 ES6(一)

      本文链接:https://www.haomeiwen.com/subject/nequaktx.html