JavaScript中实现x等于1的等值比较方法是什么?

2026-04-27 21:231阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2404个文字,预计阅读时间需要10分钟。

JavaScript中实现x等于1的等值比较方法是什么?

前言,某次面试,面试官突然问道:如何让x+等于1,且x+等于2,且x+等于3的等式成立?话音刚落,笔者立刻马失前蹄,意识消失,双眼一黑,双腿一软,心里暗骂:什么玩意儿!突然,当时没听懂。

前言

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

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

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

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

JavaScript中实现x等于1的等值比较方法是什么?

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

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

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

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

  • (3.1) 对于 ==,将引用类型转化为基础类型,进行“值”比较
  • (3.2) 因为类型不同,=== 结果为 false

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

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

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

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

  • 如果Type(x)等于Type(y)ES5 规范 11.9.3.1这样定义:
  • 如果Type(x)Undefined,返回true
  • 如果Type(x)Null,返回true
    • 如果Type(x)Number,则
    • 如果xNaN,返回false
    • 如果yNaN,返回false
    • 如果xy的数字值相同,返回true
    • 如果x+0y-0,返回true
    • 如果x-0y+0,返回true
  • 如果Type(x)String,则如果xy是字符的序列完全相同(相同的长度和相同位置相同的字符),则返回true。否则,返回false
  • 如果Type(x)Boolean,则如果xy都为true或都为false,则返回true。否则,返回false
  • 如果xy指向同一对象,则返回true。否则,返回false

null 和 undefined 之间的相等比较

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

  • 如果xnullyundefined,则结果为true
  • 如果xundefinedynull,则结果为true

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

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

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这样定义:

  • 如果Type(x)是数字,Type(y)是字符串,则返回x==ToNumber(y)的结果。
  • 如果Type(x)是字符串,Type(y)是数字,则返回ToNumber(x)==y的结果。

var a = 42; var b = "42"; a === b; // false a == b; // true 复制代码

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

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

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

ES5 规范 11.9.3.6-7这样定义:

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

仔细分析例子,首先:

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做如下规定:

  • 如果Type(x)是字符串或数字,Type(y)是对象,则返回x==ToPrimitive(y)的结果;
  • 如果Type(x)是对象,Type(y)是字符串或数字,则返回ToPromitive(x)==y的结果。

什么是 toPrimitive() 函数?

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

**函数结构:**toPrimitive(input, preferedType?)

参数解释:

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

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

执行过程:

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

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

valueOf 和 toString 的优先级:

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

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

const x = { val: 0, valueOf: () => { x.val++ return x.val }, }

或者:

const x = { val: 0, toString: () => { x.val++ return x.val }, }

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

到此这篇关于JavaScript中如何让 x == 1 && x == 2 && x == 3 等式成立的文章就介绍到这了,更多相关JS 让 x == 1 && x == 2 && x == 3 成立内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

本文共计2404个文字,预计阅读时间需要10分钟。

JavaScript中实现x等于1的等值比较方法是什么?

前言,某次面试,面试官突然问道:如何让x+等于1,且x+等于2,且x+等于3的等式成立?话音刚落,笔者立刻马失前蹄,意识消失,双眼一黑,双腿一软,心里暗骂:什么玩意儿!突然,当时没听懂。

前言

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

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

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

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

JavaScript中实现x等于1的等值比较方法是什么?

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

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

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

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

  • (3.1) 对于 ==,将引用类型转化为基础类型,进行“值”比较
  • (3.2) 因为类型不同,=== 结果为 false

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

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

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

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

  • 如果Type(x)等于Type(y)ES5 规范 11.9.3.1这样定义:
  • 如果Type(x)Undefined,返回true
  • 如果Type(x)Null,返回true
    • 如果Type(x)Number,则
    • 如果xNaN,返回false
    • 如果yNaN,返回false
    • 如果xy的数字值相同,返回true
    • 如果x+0y-0,返回true
    • 如果x-0y+0,返回true
  • 如果Type(x)String,则如果xy是字符的序列完全相同(相同的长度和相同位置相同的字符),则返回true。否则,返回false
  • 如果Type(x)Boolean,则如果xy都为true或都为false,则返回true。否则,返回false
  • 如果xy指向同一对象,则返回true。否则,返回false

null 和 undefined 之间的相等比较

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

  • 如果xnullyundefined,则结果为true
  • 如果xundefinedynull,则结果为true

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

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

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这样定义:

  • 如果Type(x)是数字,Type(y)是字符串,则返回x==ToNumber(y)的结果。
  • 如果Type(x)是字符串,Type(y)是数字,则返回ToNumber(x)==y的结果。

var a = 42; var b = "42"; a === b; // false a == b; // true 复制代码

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

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

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

ES5 规范 11.9.3.6-7这样定义:

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

仔细分析例子,首先:

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做如下规定:

  • 如果Type(x)是字符串或数字,Type(y)是对象,则返回x==ToPrimitive(y)的结果;
  • 如果Type(x)是对象,Type(y)是字符串或数字,则返回ToPromitive(x)==y的结果。

什么是 toPrimitive() 函数?

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

**函数结构:**toPrimitive(input, preferedType?)

参数解释:

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

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

执行过程:

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

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

valueOf 和 toString 的优先级:

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

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

const x = { val: 0, valueOf: () => { x.val++ return x.val }, }

或者:

const x = { val: 0, toString: () => { x.val++ return x.val }, }

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

到此这篇关于JavaScript中如何让 x == 1 && x == 2 && x == 3 等式成立的文章就介绍到这了,更多相关JS 让 x == 1 && x == 2 && x == 3 成立内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!