前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何让 x == 1 && x == 2 && x == 3 等式成立

如何让 x == 1 && x == 2 && x == 3 等式成立

作者头像
政采云前端团队
发布2022-12-01 11:10:12
5290
发布2022-12-01 11:10:12
举报
文章被收录于专栏:采云轩采云轩

如何让 x == 1 && x == 2 && x == 3 等式成立 https://www.zoo.team/article/comparison-operation

某次面试,面试官突然问道:“如何让 x 等于 1 且让 x 等于 2 且让 x 等于 3 的等式成立?

话音刚落,笔者立马失去意识,双眼一黑,两腿一蹬,心里暗骂:什么玩意儿!

虽然当时没回答上来,但觉得这题非常有意思,便在这为大家分享下后续的解题思路:

宽松相等 == 和严格相等 === 都能用来判断两个值是否“相等”,首先,我们要明确上文提到的等于指的是哪一种,我们先看下二者的区别:

(1) 对于基础类型之间的比较,== 和 === 是有区别的:

  • 不同类型间比较,== 比较“转化成同一类型后的值”看“值”是否相等,=== 如果类型不同,其结果就是不等
  • 同类型比较,直接进行“值”比较,两者结果一样。

(2) 对于引用类型之间的比较,== 和 === 是没有区别的,都进行“指针地址”比较。

(3) 基础类型与引用类型之间的比较,== 和 ===是有区别的:

代码语言:javascript
复制
因为类型不同,=== 结果为 false对于 ==,将引用类型转化为基础类型,进行“值”比较。

“== 允许在相等比较中进行强制类型转换,而 === 不允许。”

由此可见,上文提到的等于指的宽松相等 ==,题目变为 “x == 1 && x == 2 && x == 3”。

那多种数据类型之间的相等比较又有哪些呢?笔者查阅了相关资料,如下所示:

同类型数据之间的相等比较

如果 Type(x) 等于 Type(y) ES5 规范 11.9.3.1 (https://262.ecma-international.org/5.1/#sec-11.9.3) 这样定义:

  1. 如果 Type(x)Undefined,返回 true
  2. 如果 Type(x)Null,返回 true
  3. 如果 Type(x)Number ,则
    • 如果 xNaN,返回 false
    • 如果 yNaN,返回 false
    • 如果 xy 的数字值相同,返回 true
    • 如果 x+0y-0,返回 true
    • 如果 x-0y+0,返回 true
  4. 如果 Type(x)String,则如果 xy 是字符的序列完全相同(相同的长度和相同位置相同的字符),则返回 true。否则,返回 false
  5. 如果 Type(x)Boolean,则如果 xy 都为 true 或都为 false,则返回 true。否则,返回 false
  6. 如果 xy 指向同一对象,则返回 true。否则,返回 false
null 和 undefined 之间的相等比较

nullundefined 之间的 == 也涉及隐式强制类型转换。ES5 规范 11.9.3.2-3 这样定义:

  1. 如果 xnullyundefined,则结果为 true
  2. 如果 xundefinedynull,则结果为 true

在 == 中,nullundefined 相等(它们也与其自身相等),除此之外其他值都不和它们两个相等。

这也就是说, 在 == 中nullundefined 是一回事。

代码语言:javascript
复制
var a = null;
var  b; 
a == b; // true
a == null; // true
b == null; // true
a == false; // false
b == false; // false
a == ""; // false
b == ""; // false
a == 0; // false
b == 0; // false
字符串和数字之间的相等比较

ES5 规范 11.9.3.4-5 这样定义:

  1. 如果 Type(x) 是数字,Type(y) 是字符串,则返回 x == ToNumber(y) 的结果。
  2. 如果 Type(x) 是字符串,Type(y) 是数字,则返回 ToNumber(x) == y 的结果。
代码语言:javascript
复制
var a = 42;

var b = "42";

a === b; // false

a == b; // true

因为没有强制类型转换,所以 a === bfalse,42 和 "42" 不相等。

根据规范,"42" 应该被强制类型转换为数字以便进行相等比较。

其他类型和布尔类型之间的相等比较

ES5 规范 11.9.3.6-7 这样定义:

  1. 如果 Type(x) 是布尔类型,则返回 ToNumber(x) == y 的结果。
  2. 如果 Type(y) 是布尔类型,则返回 x == ToNumber(y) 的结果。

仔细分析例子,首先:

代码语言:javascript
复制
var x = true;

var y = "42";

x == y; // false

Type(x) 是布尔值,所以 ToNumber(x)true 强制类型转换为 1,变成 1 == "42",二者的类型仍然不同,"42" 根据规则被强制类型转换为 42,最后变成 1 == 42,结果为 false

对象和非对象之间的相等比较

关于对象(对象 / 函数 / 数组)和标量基本类型(字符串 / 数字 / 布尔值)之间的相等比较,ES5 规范 11.9.3.8-9 做如下规定:

  1. 如果 Type(x) 是字符串或数字,Type(y) 是对象,则返回 x == ToPrimitive(y) 的结果。
  2. 如果 Type(x) 是对象,Type(y) 是字符串或数字,则返回 ToPromitive(x) == y 的结果。
什么是 toPrimitive() 函数?

应用场景:JavaScript 中,如果想要将对象转换成基本类型时,再从基本类型转换为对应的 String 或者 Number,实质就是调用 valueOftoString 方法,也就是所谓的拆箱转换。

函数结构:toPrimitive(input, preferedType)

参数解释:

input 是输入的值,即要转换的对象,必选。

preferedType 是期望转换的基本类型,他可以是字符串,也可以是数字。选填,默认为 number

执行过程:

如果转换的类型是 number,会执行以下步骤:

  1. 如果 input 是原始值,直接返回这个值。
  2. 否则,如果 input 是对象,调用 input.valueOf(),如果结果是原始值,返回结果。
  3. 否则,调用input.toString()。如果结果是原始值,返回结果。
  4. 否则,抛出错误。如果转换的类型是 string,2 和 3 会交换执行,即先执行 toString() 方法。

valueOftoString 的优先级:

  1. 进行对象转换时 (alert(对象)),优先调用 toString 方法,如没有重写 toString 将调用 valueOf 方法,如果两方法都不没有重写,但按 ObjecttoString 输出。
  2. 进行强转字符串类型时将优先调用 toString 方法,强转为数字时优先调用 valueOf
  3. 在有运算操作符的情况下,valueOf 的优先级高于 toString

由此可知,若 x 为对象时,我们改写 xvalueOftoString 方法可以让标题的等式成立:

代码语言:javascript
复制
const x = {
  val: 0,
  valueOf: () => {
    x.val++
    return x.val
  },
}

或者:

代码语言:javascript
复制
const x = {
  val: 0,
  toString: () => {
    x.val++
    return x.val
  },
}

给对象 x设置一个属性 val并赋值为 0,并修改其 valueOftoString 方法,在 “x == 1 && x == 2 && x == 3”判断执行时,每次等式比较都会触发 valueOftoString 方法,都会执行 val++ ,同时把最新的 val 值用于等式比较,三次等式判断时 val 值分别为 1、2、3 与等式右侧的 1、2、3 相同,从而使等式成立。

看下运行结果,果不其然,真想给自己点个赞。当然,让标题的等式成立的方法肯定不止这一种,留言区期待你的回复~

参考文档:

《你不知道的 JavaScript(中卷)》

《== 和 === 区别》(https://blog.csdn.net/yyychocolate/article/details/108089477) 作者:Bliss_妍

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 政采云技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 同类型数据之间的相等比较
  • null 和 undefined 之间的相等比较
  • 字符串和数字之间的相等比较
  • 其他类型和布尔类型之间的相等比较
  • 对象和非对象之间的相等比较
  • 什么是 toPrimitive() 函数?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档