这可能是你学习ES7遗漏的知识点

7,075 阅读3分钟

小云是一枚还没有脱发的程序员,最近看到ES热度这么高,决定蹭一波热度。

ES7新增的特性

  • Array.prototype.includes
  • **

**

小云首先看到了ES7中新增的**运算符,心中暗喜:这么简单?

  8 ** 3 // 512
  Math.pow(8, 3) // 512

但是小云喜欢瞎折腾,于是他又敲了下列代码:

  2 ** 2 ** 0 // 2

结果竟然是2,小云带着疑惑查了查资料,原来**运算符是右结合的:

  (2 ** 2) ** 0 // 1

小云终于得到了自己预期的结果,而且还发现了底数的前面不能紧跟一元运算符,即使是+也不行。

Array.prototype.includes

Tip: 为什么这个方法不叫contains呢?因为一些Bug,它被重命名为includes

接下来,小云开始学习includes方法:

  [1, 2, 1].includes(1) // true

小云又敲下了之前用来判断数组中的元素是否存在的代码:

  if ([1, 2, 1].indexOf(1) !== -1) {
    // true
  }

哇!终于可以摆脱那个令人讨厌的!== -1了。

难道这两个方法仅仅是在返回值上有区别吗?小云这次决定不再瞎折腾,直接移步ES7文档

数个小时之后,小云要开始他的表演了。

ES标准的相等比较算法

  • The Abstract Equality Comparison Algorithm (==)
  • The Strict Equality Comparison Algorithm (===)
  • SameValue (Object.is())
  • SameValueZero (暂未提供API)

对于前两个大家再熟悉不过了,在我刚学JS的时候,只是通过自己长期累积的经验去区别两者的差异:

  [1, 2, 3] == '1,2,3' // true
  ['1'] == 1 // true

以至于遇到上述情况惊叹不已,但是了解原理之后,一切变得那么的简单。

The Abstract Equality Comparison Algorithm

  • 当类型相同时,特殊性在于NaN, -0, 0。
  NaN == NaN // false
  -0 == 0 // true
  • 当类型不同时,第一条准则是:null与undefined相等
  • 当类型不同时,第二条准则是:所有的比较最终多会转化为数值的比较,而它转化的优先级是Boolean => Object => String

前面两条不难理解,通过['1'] == true比较的过程,熟悉一下第三条规则:

  • 将右边的Boolean类型转化为Number类型, 转化为 ['1'] == 1
  • 将左边的Object类型转化为原始值,转化为 '1' == 1
  • 将左边的String类型转化为Number类型, 转化为 1 == 1

这时你再遇到:

  [] == false // true

是不是很轻松就知道结果了。

The Strict Equality Comparison Algorithm

对于这个算法需要注意的地方是在Number类型的比较上:

  NaN === NaN // false
  -0 === 0 // true

Tip: 上述方法的分析多是基于ES5.1,在ES6中都有细微的改变,比如加入Symbol的比较。

SameValue

对于熟练使用ES6的小伙伴,多知道Object.is()这个方法:

  Object.is(NaN, NaN) // true
  Object.is(0, -0) // false

而Object.is内部采用的比较算法就是SameValue(x, y),而它与 === 的区别也正是这两种情况。

SameValueZero

但是你在使用es6中有没有疑惑这种情况:

  const s = new Set()
  s.add(0)
  s.add(NaN)
  s.has(-0) // true
  s.has(NaN) // true

是不是与上述的三种算法的表现多不一样,这就是第四种比较算法SameValueZero,它与SameValue的区别主要在于0与-0是否相等。

所以你在实践includes方法时,遇到:

  const a = [0, NaN]
  a.includes(-0) // true
  a.includes(NaN) // true

就不用大惊小怪了,因为includes内部使用的比较算法就是SameValueZero。

参考文献


    喜欢本文的小伙伴们,欢迎关注我的订阅号超爱敲代码,查看更多内容.