'5' > 3 凭什么成立?90% 的人卡在这一关

0 阅读5分钟



大家好,我是31 岁的小米

如果你刷过我的文章就知道,我有个习惯:不太爱一上来就丢概念。因为我一直觉得,技术如果只剩下概念和规则,那跟背菜谱没啥区别;可一旦它能和生活对上号,你就会突然发现“哦,原来是这么回事。”

今天我们聊的主角,是 JavaScript 里一个特别“日常”,却又特别容易被忽略的东西——关系操作符

别看它名字朴实无华,什么 >、<、>=、<=、instanceof、in,面试官一旦顺着它往下问,能从“你会不会 JS”一路问到“你对 JS 理解有多深”。

所以今天,我们不背书,不念定义。我给你讲一个故事。

故事开场:JS 江湖的“比武大会”

在 JavaScript 江湖里,每年都会举办一次盛大的活动,叫做: “关系操作符比武大会”

规则很简单,所有选手排队上台,两两对决,裁判只做一件事:

判断:你俩,谁更大?谁更小?谁有没有资格?谁在不在这个圈子里?

最后的裁判只会给出一个结果:true 或 false

是的,关系操作符的终极使命,就是产出布尔值

第一组出场选手:>、< —— 最朴素的力量型选手

1、数字 vs 数字:毫无悬念

故事一开始,最简单的选手登场了。

这就像两个成年人掰手腕,谁力气大,谁赢

JS 心里也很清楚:“这俩都是 Number,不用多想,直接比。”

没有套路,没有陷阱。

2、字符串 vs 字符串:看起来是比大小,其实在比“字典”

接下来,上台的是两个“文化人”。

很多人第一眼就懵了:“apple 怎么会比 banana 大?”

别急,小米在这儿插一句人生经验:JS 比字符串,从来不看你‘语义’,只看你‘字典顺序’。

就像查新华字典一样:

  • 先比第一个字符
  • 如果一样,再比下一个
  • 直到分出胜负

所以:

其实是:

  • c == c
  • a == a
  • t > r

于是,true。

关键结论:字符串比较,本质是字符编码的逐位比较。

真正的江湖险恶:数字 vs 字符串

故事从这里开始变得不对劲了。

1、当“文化人”和“力量型选手”相遇

你可能会问:“一个字符串,一个数字,JS 你是怎么比的?”

答案是:只要关系操作符里出现了非字符串对字符串的比较,JS 会先把它们都转成数字。

也就是说:

于是,true。

2、再来一个经典翻车现场

为什么?因为:

  • 两边都是字符串
  • 不会转数字
  • 按字典顺序比

于是 '2' 排在 '10' 前面。

面试官最爱问的一句话: '2' > '10' 为什么是 true?

如果你能把“是否发生类型转换”讲清楚,这一题基本就稳了。

>= 和 <=:不仅要比大小,还要讲“是否平等”

1、表面很直观,底层却很“聪明”

看起来没啥问题。但 JS 在内部,其实干了两步:

x >= y等价于 !(x < y)

是的,它不是直接比“是否大于等于”,而是先问一句:“你是不是小于它?”

如果不是,那就赢了。

2、这在类型转换时,尤其重要

JS 会先转成数字,再比较。

隐藏 Boss:instanceof —— 身份审查官

故事进行到一半,一个穿制服、拿证件的角色走了出来。它不关心你多大、多小,只问一句:

“你是不是我这个家族的人?”

1、instanceof 是什么?

它判断的是:Constructor.prototype 是否出现在 obj 的原型链上

说人话就是:“你祖上是不是我家这条线的?”

2、一个很生活化的比喻

想象一下:

  • Array 是“数组世家”
  • [] 是一个具体的人

意思是:“你祖上是不是数组家族的?”

3、原型链一拉长,事情就更有意思了

因为:

一句话总结: instanceof 看的是“血统”,不是“长相”。

in 操作符:小区门口的保安

接下来出场的是 in。它不像 instanceof 那样查族谱,它更像是:

“这个属性,在不在你这儿(或者你祖上)?”

1、基本用法

虽然 length 不是你自己定义的,但它在原型链上,所以算“在”。

2、再来一个容易混淆的点

很多新手会惊讶:“我又没写 toString 啊?”

是的,但你继承了它。in 会沿着原型链一路往上找。

关系操作符 vs 相等操作符:千万别站错队

这里我要专门停下来强调一件事。关系操作符 ≠ 相等操作符

它们的比较规则完全不同。例如:

关系操作符更关注“能不能排个顺序”,相等操作符更关注“是不是同一个东西”。

一道真实的面试题,把关系操作符全串起来

来,给你一道综合题。

你先别急着答。JS 的思路是这样的:

  1. a 和 b 都不是基本类型
  2. 关系比较 → 先调用 valueOf / toString
  3. [10].toString() → '10'
  4. [20].toString() → '20'
  5. '10' < '20' → true(字符串比较)

最终结果:true

给初学者的 5 条“保命经验”

写到这里,我给你总结 5 条血泪经验

  1. 关系操作符的结果,一定是 boolean
  2. 是否发生类型转换,是理解一切的关键
  3. 字符串 vs 字符串 → 字典序
  4. 只要不是字符串 vs 字符串 → 尝试转数字
  5. instanceof 看原型链,in 看属性是否存在(含继承)

总结

很多人学 JavaScript,总觉得它“怪”“不严谨”“反直觉”。但说句实在话:

JS 不是乱,它只是非常“忠于规则”。

关系操作符,就是最好的例子。你一旦理解了它背后的“裁判逻辑”,那些看起来诡异的结果,反而会变得异常合理。

END

如果你觉得这篇文章对你有帮助,欢迎点个在看,或者转给那个总是被 '2' > '10' 搞懵的朋友

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!

我们,下篇再见。