奇怪的问题 a==1 a==2 a==3

news/2024/7/7 21:35:53

a == 1 && a == 2 && a == 3

题目很简单,只要让if语句中的判断条件成立即可。

if (a == 1 && a == 2 && a == 3) {
	console.log('win!!!');
}

首先分析题目,题目的意思只要我们能够让a同时与1,2,3相等的话,那么此时就成功了。很显然此时a并不能只是一个普通的值,因为如果a只是一个普通值的话,它是没有办法做到同时与三个值相同的。这条思路行不通,我们需要再想想其它的方法。
其实我们可以从==运算符下手,提到 == 我们可以联想到隐式类型转换,那么我们可不可以通过隐式类型转换来处理这道题呢,分析一下。
既然牵扯到隐式类型转换,无非就存在下面几种转换的规则:

  1. toPrimitive()Symbol.toPrimitive => valueOf => toString

将值转为原始值(原始类型)

  1. toNumber()Symbol.toPrimitive => valueOf => toString

将值转为数字

  1. toString()Symbol.toPrimitive => toString => valueOf

将值转为字符串
熟悉完规则后,我们再来看看题目。虽然a不能是原始值,但是我们可以将a设置为一个对象的形式,当对象与数值进行==运算的时候,是会执行toPrimitive规则的隐式转换逻辑。

var a = {
	step: 0,
	toString() {
		return ++this.step; 
	}
}
if (a == 1 && a == 2 && a == 3) {
	console.log('win');
}

a === 1 && a === 2 && a === 3

那么如果替换稍微变换的话,那么我们又该如何操作呢?刚刚是==运算符,是存在隐式转换的问题。而如果此时是===严格相等的话,那么就不存在隐式转换的问题。那么我们又该如何设计呢?
既然现在的情况是不存在隐式转换的问题,那么我们就没有办法通过valueof/toString方法去解决这个问题了,因为此时是不会调用toString、valueof方法。
我们再次分析if(a === 1 && a === 2 && a === 3)题目,当在执行a === 1的时候,程序是要去访问a的值,这样才能够进行对比。既然存在访问a这个操作,那么我们是不是可以通过数据劫持的方式来对a值进行处理呢?

if (a === 1 && a === 2 && a === 3) {
	console.log('win!!!');
}

如果用到数据劫持的话,我们可以使用Object.defineProperty()方法来处理。但是defineProperty是需要在对象上定义属性,而我们的a属性放在哪里比较合适呢?当然是存放在window对象上比较合适。所以我们可以这样去做:

var step = 0;
Object.defineProperty(window, 'a', {
	get () {
		return ++step;
	}
});
if (a === 1 && a === 2 && a === 3) {
	console.log('win!!!');
}

再次改变一下题目,如果题目换为下面的方式,又该如何操作呢?

if (obj.a === 1 && obj.a === 2 && obj.a === 3) {
	console.log('win!!!');
}

很简单,也是数据劫持。但是我们可以不用defineProperty对象定义属性的方式去做,我们可以直接在对象中通过语法糖的方式进行处理。比如说像下面一样去做:
get、set函数是直接可以写在对象内部中去。

var obj = {
	_step: 0,
	get a() {
		return ++ this._step;
	}
}

if (obj.a === 1 && obj.a === 2 && obj.a === 3) {
	console.log('win!!!');
}

http://lihuaxi.xjx100.cn/news/1834976.html

相关文章

leetcode算法之链表

目录 1.两数相加2.两两交换链表中的节点3.重排链表4.合并K个升序链表5.K个一组翻转链表 1.两数相加 两数相加 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(…

Swagger在php和java项目中的应用

Swagger在php和java项目中的应用 Swagger简介Swagger在java项目中的应用步骤常用注解 Swagger在php项目中的应用 Swagger简介 Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。 总体目标是使客户端和文件系统作为服务器以…

并行与分布式计算 第六章 云计算

文章目录 并行与分布式计算 第六章 云计算6.1 什么是云计算6.2虚拟化技术 并行与分布式计算 第六章 云计算 6.1 什么是云计算 云计算是通过互联网(“云”)提供计算服务(包括服务器、存储、数据库、网络、软件、分析和智能)你只需…

Linux内核--内存管理(二)物理内存分页机制

一、引言 二、物理内存模型 ------>2.1、平坦内存模型(Flat Memory Model) ------>2.2、对称多处理 SMP(Symmetric MultiProcessing) ------>2.3、非均衡访存模型 NUMA(Non-Uniform Memory Access) 三、节点、区域和页 ------>3.1、节点 ------>3.2、区域…

13年老鸟总结,性能测试方法汇总+性能响应很慢排查方法(详全)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、性能测试包含哪…

4D Gaussian Splatting:用于实时的动态场景渲染

Wu G, Yi T, Fang J, et al. 4d gaussian splatting for real-time dynamic scene rendering[J]. arXiv preprint arXiv:2310.08528, 2023. 更多参考资料如下: 文章总结:4D Gaussian Splatting for Real-Time Dynamic Scene Rendering;疑难问…

我的创作纪念日-----MySql服务

MySql服务 1.什么是数据库 1.1.数据 描述事物的符号记录,可以是数字文字、图形、图像、声音、语言等,数据有多种形式,它们都可以经过数字化后存入计算机。 1.2.数据库 存储数据的仓库,是长期存放在计算机内、有组织、可共享的大…

OD机考真题搜集:导师请吃火锅

题目 入职后,导师会请你吃饭,你选择了火锅, 火锅里会在不同时间下很多菜, 不同食材要煮不同时间,才能变得刚好合适, 你希望吃到最多的刚好合适的菜, 但是你的手速不够快用m代替手速, 每次下手捞菜后至少要过m秒, 才能再捞(每次只能捞一个)那么用最合理的策略, 最多…