主持人注意:请抵制编辑代码或删除此通知的冲动。空白模式可能是问题的一部分,因此不应进行不必要的篡改。如果您处于“空白是无关紧要的”阵营,您应该能够接受代码。

在JavaScript中,(a==1&&a==2&&a==3)是否有可能求值为真?

这是一家大型科技公司提出的面试问题。事情发生在两周前,但我仍在努力寻找答案。我知道我们在日常工作中从未编写过这样的代码,但我很好奇。


当前回答

是的,您可以这样做,请参见以下JavaScript代码:

让a=0//创建一个变量并为其赋值如果(a!==1&&a!==2&&a!==3){console.log(“true”)}

解决方案说明:

简单地说,我们加上不等号在==符号之前,以便我们告诉语言这些值是不等于变量中的值

其他回答

如果没有正则表达式就无法执行任何操作:

变量a={r: /\d/g,valueOf:函数(){返回此.r.exec(123)[0]}}如果(a==1&&a==2&&a==3){console.log(“!”)}

它之所以有效,是因为当Object与基元(如Number)进行比较时调用了自定义valueOf方法。主要技巧是,a.valueOf每次都会返回新值,因为它使用g标志对正则表达式调用exec,这会导致每次找到匹配项时更新该正则表达式的lastIndex。所以第一次this.r.lastIndex==0时,它匹配1并更新lastIndex:this.r.lastIndex==1,所以下次regex将匹配2,依此类推。

这是可能的!

变量i=0;具有({获取a(){返回++i;}}) {如果(a==1&&a==2&&a==3)console.log(“wohoo”);}

这在with语句中使用getter,让一个求值为三个不同的值。

…这仍然不意味着这应该在实际代码中使用。。。

更糟糕的是,使用==也可以使用此技巧。

变量i=0;具有({获取a(){返回++i;}}) {如果(a!==a)console.log(“是的,这是打印的。”);}

实际上,在每种编程语言中,问题第一部分的答案都是“是”。例如,这是在C/C++的情况下:

#define a   (b++)
int b = 1;
if (a ==1 && a== 2 && a==3) {
    std::cout << "Yes, it's possible!" << std::endl;
} else {
    std::cout << "it's impossible!" << std::endl;
}

老实说,不管有没有一种方法可以评估它的真实性(正如其他人所展示的,有多种方法),我要寻找的答案是,作为一个已经进行了数百次面试的人来说,大致如下:

“嗯,也许是的,在一些奇怪的情况下,这些情况对我来说不是很明显……但如果我在真实的代码中遇到了这种情况,我会使用常见的调试技术来弄清楚它是如何以及为什么在做它正在做的事情,然后立即重构代码以避免这种情况……但更重要的是:我绝对不会在一开始就写代码,因为这就是复杂代码的定义,我努力不写复杂代码”。

我想有些面试官会对提出一个显然是非常棘手的问题感到愤怒,但我不介意有意见的开发人员,特别是当他们能够用合理的想法来支持这一点,并将我的问题融入到一个关于自己的有意义的陈述中时。

我没有看到这个答案已经发布了,所以我也会把这个加入到混合中。这与Jeff使用半宽朝鲜文空格的回答类似。

变量a=1;变量a = 2.varа=3;如果(a==1&&a == 2 && а == 3) {console.log(“你好!”)}

你可能会注意到与第二个略有不同,但第一个和第三个与肉眼完全相同。所有3个字符都是不同的:

a-拉丁文小写aa - 全宽拉丁文小写Aа-西里尔文小写A

通用术语是“同字形”:看起来相同的不同unicode字符。通常很难找到三个完全无法区分的,但在某些情况下,你可能会很幸运。A、 Α、А和Ꭺ 会更好地工作(拉丁字母A、希腊字母Alpha、西里尔字母A和切罗基字母A);不幸的是,希腊语和切罗基语小写字母与拉丁字母A:α,ꭺ, 因此对上面的片段没有帮助)。

有一整类的同字形攻击,最常见的是假域名(例如,wikipediа.org(西里尔文)vs wikipedia.org(拉丁语)),但它也可以在代码中出现;通常被称为隐藏(正如一篇评论中所提到的,[隐藏]问题现在在PPCG上已不再是话题,但在过去,这类问题会成为一种挑战)。我使用这个网站来查找用于这个答案的同字形。