什么时候 a == 1 && a == 2 && a == 3 为 true?

简介: 什么时候 a == 1 && a == 2 && a == 3 为 true?

说明

在网上看到的一个面试题:什么时候 a == 1 && a == 2 && a == 3 为 true?

觉得很有趣,记录一下。(当然我想不出来_(:3」∠)_).



分析

关于要这个表达式成立, a == 1 && a == 2 && a == 3 的每一个条件都要为 true.


1、显然,如果 每次调用 变量 a ,a 的 值都固定不变,肯定没戏。

2、所以,要想使 a == 1、a == 2、a == 3 都为 true,就是只能每次调用 a 时,a 的 值每次 加 1。


注意:

   当两个类型不同时进行 == 比较时,会将一个类型转为另一个类型,然后再进行比较。


1、Object类型与Number类型进行比较时,Object类型会转换为Number类型。

   对象转换为 Number 时,会尝试调用 Object.valueOf()和Object.toString()来获取对应的数字基本类型。


2、数组调用toString()会隐含调用Array.join()方法。



解法一:对象类型转换


1、覆盖自定义对象的 valueOf() 方法


Object.prototype.valueOf()-参考文档

Object 的 valueOf() 方法会返回指定对象的原始值。


不同类型对象的valueOf()方法的返回值。


对象 返回值
Array 返回数组对象本身。
Boolean 布尔值。
Date 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。
Function 函数本身。
Number 数字值。
Object 对象本身。这是默认情况。
String 字符串值。
Math 和 Error 对象没有 valueOf 方法。



代码实现:

var val = 0
var a = {
  valueOf: function() {
    console.log('valueOf-->', val)
    return ++val
  }
}
// 分开打印
console.log('Number-->', Number(a))
console.log('Number-->', Number(a))
console.log('Number-->', Number(a))
/* 输出结果:
  valueOf--> 0
  Number--> 1
  valueOf--> 1
  Number--> 2
  valueOf--> 2
  Number--> 3
*/
// 或者直接打印
console.log(a == 1 && a == 2 && a == 3) // 输出:true



2、覆盖自定义对象的 toString() 方法

代码实现:(跟上面的有点类似)

var a = {
  i: 1,
  toString: function() {
    console.log('toString-->', a.i)
    return a.i++
  }
}
// 分开打印
console.log('Number-->', Number(a))
console.log('Number-->', Number(a))
console.log('Number-->', Number(a))
/* 输出结果:
  toString--> 1
  Number--> 1
  toString--> 2
  Number--> 2
  toString--> 3
  Number--> 3
*/
// 或者直接打印
console.log(a == 1 && a == 2 && a == 3) // 输出:true


代码分析:


object --> number (引用类型转换为原始类型)


   1、先调用object的valueOf方法,如果为原始值,则return,否则第2步

   2、调用object的toString方法,如果为原始值,则return,否则第3步

   3、抛出TypeError异常


如果到这里还是不怎么清晰的话:(请看下图:里面涉及ToPrimitive函数)

由Dry同学整理提供下图


aHR0cHM6Ly91c2VyLWdvbGQtY2RuLnhpdHUuaW8vMjAxOS8xMS8yOC8xNmViMjM0NWFkNzRiMDEx.png


解法二:数组类型转换

var a = [1, 2, 3];
a.join = a.shift; // 核心操作转移
console.log(a == 1 && a == 2 && a == 3);
// valueOf --> toString --> join


代码分析:

上面代码 a.join = a.shift; 数组 a 的 join 被 shift 方法覆盖。

而数组调用 toString() 会隐含调用 Array.join() 方法。

从而达到一个目的:对数组 [1, 2, 3] 执行 shift 方法操作。



解法三:创建属性 defineProperty 的 get

defineProperty-参考文档

var val = 0;
Object.defineProperty(window, 'a', {
  get: function() {
    return ++val;
  }
});
console.log(a == 1 && a == 2 && a == 3);


目录
相关文章
|
7月前
|
缓存 Java API
为什么Java中“1000==1000”为false,而”100==100“为true
为什么Java中“1000==1000”为false,而”100==100“为true
48 0
|
4月前
|
存储 缓存 Java
为什么在Java中1000==1000为false,而100==100却为true?
为什么在Java中1000==1000为false,而100==100却为true?
86 1
|
7月前
|
JavaScript 前端开发 安全
== 和 ===什么区别呀?
== 和 ===什么区别呀?
125 0
|
7月前
! [ ] == ! [ ] 和 ! [ ] == [ ] 结果是什么? 为什么?
! [ ] == ! [ ] 和 ! [ ] == [ ] 结果是什么? 为什么?
47 0
|
JavaScript 前端开发
== 和 ===区别,分别在什么情况使用
== 和 ===区别,分别在什么情况使用
82 1
|
前端开发
return false得使用
return false得使用
51 0
|
Java
==和equals()
==和equals()
88 0
|
Python
a is b 为 True,a == b 一定为 True 吗?
a is b 为 True,a == b 一定为 True 吗?
124 0
a==b,b==c都为true,那a==c一定为true吗???
a==b,b==c都为true,那a==c一定为true吗???
a==b,b==c都为true,那a==c一定为true吗???