文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

面试官: (a==1 && a==2 && a==3) 能否在 JavaScript 中为“真”?

2024-12-01 14:11

关注

那一刻,我被这个问题吓了一跳,以为面试官在开玩笑。

但当我看到他的“微笑”时,一种“你一定不知道答案”的感觉掠过我的脑海,这绝对不是一个容易解决的问题。

文章将给出6个专业答案,让我们马上开始吧。

解决方案一:valueOf && toString

第一个解决方案非常简单,相信你在阅读此代码后会有一个想法。

let a = {
name: 'fatfish',
toString () {
return 'medium'
}
}


if (a == 'medium') {
console.log('hello medium')
}

太神奇了,这是怎么回事? 别担心,我的朋友,我会尽力解释原因。

解释部分隐式转换规则

在 JavaScript 中使用 == 比较两个值时,会执行以下操作:

比较规则如下表所示:

从表中可以得到一些信息。 为了使 (a == 1),a 只能是以下几种情况:

  1. a 的类型是 String,可以转换为数字 1('1' == 1 => true)。
  2. a 的类型是布尔值,可以转换为数字 1 (true == 1 => true)。
  3. a的类型是Object,可以通过“转换机制”转换为数字1。

对象到原始类型的“转换机制”

规则 1 和规则 2 没有什么特别之处,我们来看看规则 3:

当对象转换为原始类型时,会调用内置的 [ToPrimitive] 函数。 

逻辑大致如下:

const obj = {
value: 1,
valueOf() {
return 2
},
toString() {
return '3'
},
[Symbol.toPrimitive]() {
return 4
}
}
obj == 4

我的朋友,感谢你非常耐心地阅读了这么长时间,我相信你心中已经有了答案。

let a = {
i: 1,
valueOf() {
return this.i++
}
}
if (a == 1 && a == 2 && a == 3) {
console.log('hello medium')
}

解决方案 2:数组 && 连接

数组对象的隐式转换也符合规则 3,但会在“toString”之前调用“join”方法。 所以你可以从这里开始。

let a = [1, 2, 3]


a.join = a.shift


if (a == 1 && a == 2 && a == 3) {
console.log('hello medium')
}

解决方案 3:使用“with”运算符

MDN 有一个关于 with 使用的警告,好像它的存在是一个错误。 我在工作中从未使用过它,但它可以用来解决这个问题。

let i = 1
with ({
get a() {
return i++
}
}) {
if (a == 1 && a == 2 && a == 3) {
console.log('hello medium')
}
}

你太聪明了,甚至不需要我解释代码的含义。

解决方案 4:Symbol.toPrimitive

我们可以使用隐式转换规则3来完成问题(看完答案你就知道为什么了!)。

const a = {
i: 1,
[Symbol.toPrimitive]() {
return this.i++
}
}
if (a == 1 && a == 2 && a == 3) {
console.log('hello medium')
}

数据劫持也是一种出路

通过隐式转换,我们做了3个答案让a == 1 && a == 2 && a == 3 返回true,你一定想到了另一个答案,数据劫持,伟大的Vue我们用它来赢得人心 数百万开发者,我们也尝试用它来解决这个面试问题。

解决方案 5:Object.defineProperty

通过劫持‘window’对象,每次读取‘a’属性时,_a加1。

let _a = 1
Object.defineProperty(window, 'a', {
get() {
return _a++
}
})
if (a == 1 && a == 2 && a == 3) {
console.log('hello medium')
}

解决方案 6:代理

还有另一种劫持数据的方式,Vue3 也用 Proxy 替换了 Object.defineProperty。

let a = new Proxy({ i: 1 }, {
get(target) {
return () => target.i++
}
})
if (a == 1 && a == 2 && a == 3) {
console.log('hello medium')
}

来源:web前端开发内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯