1. 首页
  2. 前端基础

null >= 0?

今天分享的文章是:null >= 0?

1 引言

null >= 0?

你是如何看待 null >= 0 为 true 这个结果的呢?要么选择勉强接受,要么跟着我一探究竟吧。

2 内容概要

大于判断

javascript 在判断 a > b 时,记住下面 21 步判断法:

  1. 调用 b 的 ToPrimitive(hit Number) 方法.
  2. 调用 a 的 ToPrimitive(hit Number) 方法.
  3. 如果此时 Result(1) 与 Result(2) 都是字符串,跳到步骤 16.
  4. 调用 ToNumber(Result(1)).
  5. 调用 ToNumber(Result(2)).
  6. 如果 Result(4) 为 NaN, return undefined.
  7. 如果 Result(5) 为 NaN, return undefined.
  8. 如果 Result(4) 和 Result(5) 是相同的数字,return false.
  9. 如果 Result(4) 为 +0, Result(5) 为 -0, return false.
  10. 如果 Result(4) 为 -0, Result(5) 为 +0, return false.
  11. 如果 Result(4) 为 +∞, return false.
  12. 如果 Result(5) 为 +∞, return true.
  13. 如果 Result(5) 为 -∞, return false.
  14. 如果 Result(4) 为 -∞, return true.
  15. 如果 Result(4) 的数值大小小于 Result(5),return true,否则 return false.
  16. 如果 Result(2) 是 Result(1) 的前缀 return false. (比如 “ab” 是 “abc” 的前缀)
  17. 如果 Result(1) 是 Result(2) 的前缀, return true.
  18. 找到一个位置 k,使得 a[k] 与 b[k] 不相等.
  19. 取 m 为 a[k] 字符的数值.
  20. 取 n 为 b[k] 字符的数值.
  21. 如果 m < n, return true,否则 return false.

ToPrimitive 会按照顺序优先使用存在的值:valueOf()、toString(),如果都没有,会抛出异常。
ToPrimitive(hit Number) 表示隐转数值类型

所以 null > 0 结果为 false

等于判断

现在看看 a == b 时的表现(三等号会严格判断类型,两等号反而是最复杂的情况)。

  1. 如果 a 与 b 的类型相同,则:
    • 如果 Type(b) 为 undefined,return true.
    • 如果 Type(b) 为 null,return true.
    • 如果 Type(b) 为 number,则:
      • 如果 b 为 NaN,return false.
      • 如果 a 为 NaN,return false.
      • 如果 a 与 b 数值相同,return true.
      • 如果 a 为 +0,b 为 -0,return true.
      • 如果 a 为 -0,b 为 +0,return true.
      • 否则 return false.
    • 如果 Type(b) 为 string,且 a 与 b 是完全相同的字符串,return true,否则 return false.
    • 如果 Type(b) 是 boolean,如果都是 true 或 false,return true,否则 return false.
    • 如果 a 与 b 是同一个对象引用,return true,否则 return false.
  2. 如果 a 为 null,b 为 undefined,return true.
  3. 如果 a 为 undefined,b 为 null,return true.
  4. 如果 Type(a) 为 number,Type(b) 为 string,返回 a == ToNumber(b) 的结果.
  5. 如果 Type(a) 为 string,Type(b) 为 number,返回 ToNumber(a) == b 的结果.
  6. 如果 Type(a) 为 boolean,返回 ToNumber(a) == b 的结果.
  7. 如果 Type(b) 为 boolean,返回 a == ToNumber(b) 的结果.
  8. 如果 Type(a) 是 string 或 number,且 Type(b) 是对象类型,返回 a == ToPrimitive(b) 的结果.
  9. 如果 Type(a) 是对象类型,且 Type(b) 是 string 或 number,返回 ToPrimitive(a) == b 的结果.
  10. 否则 return false.

所以 null == 0 走到了第 10 步,返回了默认的 false

大于等于判断

javascript 是这么定义大于等于判断的:

如果 a < b 为 false,则 a >= b 为 true

所以 null >= 0 为 true,因为 null < 0 是 false.

3 精读

关于 toPrimitive

拓展一下,我们可以通过 Symbol.toPrimitive 定义某个 class 的 ToPrimitive 行为,比如:


class AnswerToLifeAndUniverseAndEverything { [Symbol.toPrimitive](hint) { if (hint === 'string') { return 'Like, 42, man'; } else if (hint === 'number') { return 42; } else { // when pushed, most classes (except Date) // default to returning a number primitive return 42; } } }

还有不按套路出牌的情况?

按上面的道理,我们可以举一反三:

{} >= {} // true

可是这是为何呢?

null >= {} // false

仔细读过上文应该不难发现,如果 ToPrimitive(hit Number) 出现了 NaN,将直接 return undefined,也就是打印出 false,而下面是隐式转换表,{} 的结果是 NaN,因此结果是 false。

4 总结

NaN 在 javascript 是个特殊存在,只有 isNaN 可以准确判断到它,而且使用它进行比较判断时,会直接 return false.

javascript 隐式转换有一套优先级规则,而且不同值的隐式转换还需要对照表记忆,还存在 ToPrimitive(hint Number) ToPrimitive(hint String) ToPrimitive(hint Boolean) 三份表,记忆起来确实有点复杂。

因此推荐比较判断时,尽量使用 ===,通过 Typescript Flow 等强类型语言约束变量类型,尽量不要做不同类型变量间的比较。

讨论地址是:精读《null >= 0?》 · Issue #36 · dt-fe/weekly

如果你想参与讨论,请点击这里,每周都有新的主题,每周五发布。

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文著作权归作者所有,如若转载,请注明出处

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:null >= 0?

链接:https://www.javascriptc.com/4980.html

« Google搜索的10个小技巧,部分适用于百度
how we position and what we compare»
Flutter 中文教程资源

相关推荐

QR code