1 引言
你是如何看待 null >= 0 为 true
这个结果的呢?要么选择勉强接受,要么跟着我一探究竟吧。
2 内容概要
大于判断
javascript 在判断 a > b
时,记住下面 21 步判断法:
- 调用 b 的 ToPrimitive(hit Number) 方法.
- 调用 a 的 ToPrimitive(hit Number) 方法.
- 如果此时 Result(1) 与 Result(2) 都是字符串,跳到步骤 16.
- 调用 ToNumber(Result(1)).
- 调用 ToNumber(Result(2)).
- 如果 Result(4) 为 NaN, return undefined.
- 如果 Result(5) 为 NaN, return undefined.
- 如果 Result(4) 和 Result(5) 是相同的数字,return false.
- 如果 Result(4) 为 +0, Result(5) 为 -0, return false.
- 如果 Result(4) 为 -0, Result(5) 为 +0, return false.
- 如果 Result(4) 为 +∞, return false.
- 如果 Result(5) 为 +∞, return true.
- 如果 Result(5) 为 -∞, return false.
- 如果 Result(4) 为 -∞, return true.
- 如果 Result(4) 的数值大小小于 Result(5),return true,否则 return false.
- 如果 Result(2) 是 Result(1) 的前缀 return false. (比如 “ab” 是 “abc” 的前缀)
- 如果 Result(1) 是 Result(2) 的前缀, return true.
- 找到一个位置 k,使得 a[k] 与 b[k] 不相等.
- 取 m 为 a[k] 字符的数值.
- 取 n 为 b[k] 字符的数值.
- 如果 m < n, return true,否则 return false.
ToPrimitive 会按照顺序优先使用存在的值:valueOf()、toString(),如果都没有,会抛出异常。
ToPrimitive(hit Number) 表示隐转数值类型
所以 null > 0 结果为 false
。
等于判断
现在看看 a == b
时的表现(三等号会严格判断类型,两等号反而是最复杂的情况)。
- 如果 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.
- 如果 a 为 null,b 为 undefined,return true.
- 如果 a 为 undefined,b 为 null,return true.
- 如果 Type(a) 为 number,Type(b) 为 string,返回 a == ToNumber(b) 的结果.
- 如果 Type(a) 为 string,Type(b) 为 number,返回 ToNumber(a) == b 的结果.
- 如果 Type(a) 为 boolean,返回 ToNumber(a) == b 的结果.
- 如果 Type(b) 为 boolean,返回 a == ToNumber(b) 的结果.
- 如果 Type(a) 是 string 或 number,且 Type(b) 是对象类型,返回 a == ToPrimitive(b) 的结果.
- 如果 Type(a) 是对象类型,且 Type(b) 是 string 或 number,返回 ToPrimitive(a) == b 的结果.
- 否则 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
等强类型语言约束变量类型,尽量不要做不同类型变量间的比较。
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=17553,转载请注明出处。
评论0