使 a === 1 a === 2 a === 3 为 true 的几种“下毒“方法
前言
这算得上是近些年的前端网红题了,曾经对这种网红题非常抵触,认为非常没有意义。
看到了不少人有做分享,有各种各样的方案,有涉及到 JS 非常基础的知识点,也不得不感叹解题者的脑洞之大。
但是,拿来做面试题为难没有看过的面试者,就非常非常不地道了。
鹤顶红
鹤顶红是武侠剧中出现最多的毒药,真的是江湖出行必备的毒药。
正常情况下,如果 let a = 1; 则,表达式的后半段必不成立。但是容易想到如果在每个阶段自增后,表达式是可能成立的。
let a = 1;
a++ === 1 && a++ === 2 && a++ === 3; // true
可是这就属于把题改了,我们需要把自增的逻辑藏起来。由于 a 是基础类型,我们基本上不可能对其做什么改造了。
但是我们如果把 a 定义到 window 上,再加上诸如 Object.defineProperty 的 api,是能够做到的。
let tmp = 1;
Object.defineProperty(window, 'a', { get: function () { return tmp++; },
})
a === 1 && a === 2 && a === 3; // true
由于 defineProperty 的限制,我们不能把 1 作为 value, 设置在属性描述符号内部,不得不外部定义一个变量。
defineProperty 在诸如 Vue2 的框架中,用的非常多,几乎是面试高频会被问到的,所以这种“毒药”是你行走前端江湖必备的。
曼陀罗
曼陀罗这个名字颇具异域风情、《神雕侠侣》中杨过就是中了此毒。
说到这里我是要将此题改为另一道类似的题目:使 a == 1 && a == 2 && a == 3 返回 true。
将严格相等改为了普通的相等,因为通常代码规范中要求使用严格相等,导致 == 不常写,故将此命名为这个异域的名字。
正因为是不严格相等,我们可以利用 JS 中的类型转换机制来下毒。
这个机制是这样的:
- 如果两个值类型相同,则之间进行比较,和全等是一样的。
- 如果一个是 null,另一个是 undefined,则相等。
- 如果一个是数值,另一个是字符串,把字符串转换为数值,再比较转换后的数值。
- 如果一个是 true,把它转成 1,再比较。
- 如果一个是 false,把它转成 0,再比较。
- 如果一个是对象,另一个是数值或字符串,会将对象转换为原始值,再比较。用到的是 valueOf() 和 toString() 方法。
我们可以利用最后一点解这个题:
const a = { value: 1, valueOf: function () { return this.value++; },
}
a == 1 && a == 2 && a == 3;
先前提到的那种解法必然也可以解这道题,但是这个写法不能用于上一道题,因为全等不会触发类型转换。
十香软筋散
此毒无色无香,药性一发作便全身筋骨酸软,数日后虽行动如常,内力半点发挥不出。毒药和解药表面无异,若中毒者再服毒药则气绝身亡。
const a = 1;
const a = 2;
const a = 3;
a === 1 && a === 2 && a === 3
你可能会说:“这段代码应该是会报错的!”。但是相信我,你复制到控制台执行一下试试。注意我这里有一个 a 是正常的 a,如果你有执行过上面别的方法,注意先刷新一下窗口。
是的 const 声明的是常量,理应抛出错误:Identifier 'haha' has already been declared。
实际上,我这里定义的三个 a 是不同的变量,有一个是 a, 一个是 ax, 一个是 ay,其中 x, y 是被我替换为 unicode 里不可见的字符,所以在上面的代码里看到的都是 a 的形式。
我目前正在使用 webstorm 编辑这篇文章,我也发现了这些不可见字符会在编辑器里显示出来“怪怪的”,如果你也打开这篇 markdown,你会发现:

构造变量名称(唯一标识符)的通用规则是:
- 名称可包含字母、数字、下划线和美元符号
- 名称必须以字母开头
- 名称也可以 $ 和 _ 开头
- 名称对大小写敏感(y 和 Y 是不同的变量)
- 保留字(比如 JavaScript 的关键词)无法用作变量名称
实际上,使用中文,甚至是 emoji 表情作为变量名称都是合法的,所以这里可以使用不可见的 unicode 字符作为变量名。
当然,如果想要运行正确,我们得偷偷的把题改了,使用我们新声明的变量,虽然它们看起来一摸一样。
这种“下毒”,真是无色无味,正像软筋散一样。
总结
这边汇总了二个针对原题的解法:通过使用 Object.defineProperty 和利用变量名称的规则的方法;
以及对它的变种题目:通过对象类型转化时默认调用 valueOf 函数的机制。
这道题至少也算给我们带来了三个 JS 基础知识点,好了,你(这道题)可以毒发身亡了。
前端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库
相关文章:
使 a === 1 a === 2 a === 3 为 true 的几种“下毒“方法
前言 这算得上是近些年的前端网红题了,曾经对这种网红题非常抵触,认为非常没有意义。 看到了不少人有做分享,有各种各样的方案,有涉及到 JS 非常基础的知识点,也不得不感叹解题者的脑洞之大。 但是,拿来…...
Canny边缘检测 双阈值检测理解
问题引入 我们用一个实际例子来引入问题 import cv2 import numpy as npimgcv2.imread("test.png",cv2.IMREAD_GRAYSCALE) # 修改图像大小 show cv2.resize(img,(500,500))v1cv2.Canny(show,120,250) v2cv2.Canny(show,50,100)# 连接图像 res np.hstack((v1,v2)…...
自动化测试:5分钟了解Selenium以及如何提升自动化测试的效果
在快节奏的技术世界里,自动化测试已经成为确保 Web 应用程序质量和性能的重要手段。自动化测试不仅加快了测试过程,还提高了测试的重复性和准确性。Selenium,作为领先的自动化测试工具之一,为测试人员提供了强大的功能来模拟用户在…...
【MySQL】——关系数据库标准语言SQL(大纲)
🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL:…...
力扣hot100 最长有效括号 动态规划
Problem: 32. 最长有效括号 文章目录 思路Code 思路 👨🏫 参考题解 Code ⏰ 时间复杂度: O ( n ) O(n) O(n) 🌎 空间复杂度: O ( n ) O(n) O(n) class Solution {public int longestValidParentheses(String s){int n s.length();…...
@RequestBody注解基础
RequestBody RequestBody注解一般与post方法使用。 一个请求中只能存在一个RequestBody注解。 RequestBody 用于接收前端传递给后端的json字符串中的数据。(处理json格式的数据) 语法格式: (RequestBody Map map) (RequestBody Object obje…...
前端基础面试题大全
一、Vue 文章目录 一、Vue1、vue 修改数据页面不重新渲染**数组/对象的响应式 ,vue 里面是怎么处理的?** 2、生命周期Vue 生命周期都有哪些?父子组件生命周期执行顺序 3、watch 和 computed 的区别4、组件通信(组件间传值…...
第一讲_HarmonyOS应用开发环境准备
HarmonyOS应用开发环境准备 1. 知识储备2. 环境搭建2.1 安装node.js2.2 配置node.js2.3 安装命令行工具2.4 安装DevEco Studio2.5 配置DevEco Studio 1. 知识储备 HarmonyOS提供了一套UI开发框架,即方舟开发框架(ArkUI框架)。方舟开发框架可…...
一、可行性研究报告模板(软件工程)
一、可行性研究报告 1.引言 1.1编写目的 1.2项目背景 1.3定义 1.4参考资料 2.可行性研究的前提 2.1要求 2.2目标 2.3条件、假定和限制 2.4可行性研究方法 2.5决定可行性的主要因素 3.对现有系统的分析 3.1处理流程…...
DBA技术栈MongoDB:简介
1.1 什么是MongoDB? MongoDB是一个可扩展、开源、表结构自由、用C语言编写且面向文档的数据库,旨在为Web应用程序提供高性能、高可用性且易扩展的数据存储解决方案。 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当…...
贪心算法 ——硬币兑换、区间调度、
硬币兑换: from book:挑战程序设计竞赛 思路:优先使用大面额兑换即可 package mainimport "fmt"func main() {results : []int{}//记录每一种数额的张数A : 620B : A//备份cnts : 0 //记录至少需要多少张nums : []int{1, 5, 10, 5…...
【已解决】namespace “Ui“没有成员 xxx
先说笔者遇到的问题,我创建一个QWidget ui文件,然后编辑的七七八八后,想要用.h与.cpp调用其,编译通过,结果报了这个错误,本方法不是普适性,但是确实解决了这个鸟问题。 问题来源 搭建ui后&…...
Spring Bean 生命周期的执行流程?
一、问题解析 Spring 生命周期全过程大致分为五个阶段:创建前准备阶段、创建实例阶段、依赖注入阶段、容器缓存阶段和销毁实例阶段。 这张是 Spring Bean 生命周期完整流程图,其中对每个阶段的具体操作做了详细介绍: (把这张图按…...
Android-三方框架的源码
ARouter Arouter的整体思路是moduelA通过中间人ARouter把路由信息的存到仓库WareHouse;moduleB发起路由时,再通过中间人ARouter从仓库WareHouse取出路由信息,这要就实现了没有依赖的两者之间的跳转与通信。其中涉及Activity的跳转、服务prov…...
AI嵌入式K210项目(15)-安全散列算法加速器
文章目录 前言一、什么是SHA256?实验原理 二、K210的安全散列算法加速器三、实验过程总结 前言 K210内置了丰富的加速器,包括神经网络处理器 (KPU),AES(高级加密加速器),APU 麦克风阵列语音数据加速计算处理器,现场可…...
Docker Consul详解与部署示例
目录 Consul构成 Docker Consul 概述 Raft算法 服务注册与发现 健康检查 Key/Value存储 多数据中心 部署模式 consul-template守护进程 registrator容器 consul服务部署(192.168.41.31) 环境准备 搭建Consul服务 查看集群信息 registrato…...
内网安全管理系统(保密管理系统)
在当今信息化的时代,企业的内网已经成为其核心资产的重要组成部分。 随着企业的快速发展和信息化程度的提升,内网安全问题日益凸显,如何保障内网的安全和机密信息的保密性,已经成为企业亟待解决的问题。 内网安全管理系统(保密管…...
.NetCore Flurl.Http 4.0.0 以上管理客户端
参考原文地址:Managing Clients - Flurl 管理客户端 Flurl.Http 构建在堆栈之上System.Net.Http。如果您熟悉HttpClient,那么您可能听说过这个建议:不要为每个请求创建一个新客户端;重复使用它们,否则将面临后…...
openssl3.2 - 官方demo学习 - smime - smenc.c
文章目录 openssl3.2 - 官方demo学习 - smime - smenc.c概述笔记END openssl3.2 - 官方demo学习 - smime - smenc.c 概述 读取X509证书, 用PKCS7加密明文(证书 明文 3DES_CBC), 保存为MIME格式的密文 openssl API的命名含义 BIO_new_file “new” a “file”, return a “…...
【EI会议征稿通知】第四届工业制造与结构材料国际学术会议(IMSM 2024)
第四届工业制造与结构材料国际学术会议(IMSM 2024) 2024 4th International Conference on Industrial Manufacturing and Structural Materials(IMSM 2024) 第四届工业制造与结构材料国际学术会议(IMSM 2024&#x…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
