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

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

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


当前回答

如果利用==的工作原理,您可以简单地创建一个带有自定义toString(或valueOf)函数的对象,该函数在每次使用时都会更改其返回的内容,以使其满足所有三个条件。

常量a={i: 1中,toString:函数(){返回a.i++;}}如果(a==1&&a==2&&a==3){console.log(“Hello World!”);}


这之所以有效,是因为使用了松散的相等运算符。使用松散相等时,如果其中一个操作数的类型与另一个不同,则引擎将尝试将其中一个转换为另一个。在左边是一个对象,右边是一个数字的情况下,它将尝试通过首先调用valueOf(如果它是可调用的)将对象转换为一个数字,否则,它将调用toString。在这种情况下,我习惯使用String,因为这是我想到的,valueOf更有意义。如果我从toString返回一个字符串,那么引擎将尝试将该字符串转换为一个数字,从而得到相同的最终结果,尽管路径稍长。

其他回答

令人惊讶的是,是的。JS中的==松散相等运算符调用被比较对象的valueOf()方法。因此,您可以创建一个类,该类返回一个内部值,然后在每次调用时递增该间隔值。这样地:

A类{构造函数(initalVal){this.val=初始值;}值Of(){返回此.val++;}}const a=新AClass(1);console.log(a==1&&a==2&&a==3)

我知道这个问题还有很多其他答案,但这就是ES6语法的用法。

注意:如果不希望发生这种情况,那么应该使用==运算符来检查strict。这样地:

A类{构造函数(initalVal){this.val=初始值;}值Of(){返回此.val++;}}const a=新AClass(1);console.log(a==1&&a==2&&a==3)

面试规则一;永远不要说不可能。

不需要隐藏角色的诡计。

窗口__定义Getter__('a',函数(){if(类型i!=='number'){//在全局命名空间中定义i,以便在运行此函数后不会丢失i=0;}返回++i;});如果(a==1&&a==2&&a==3){console.log(“哦,亲爱的,我们做了什么?”);}

我无法抗拒——其他答案毫无疑问是正确的,但你真的无法通过以下代码:

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

注意if语句中奇怪的空格(我从你的问题中复制的)。它是半宽朝鲜文(对于不熟悉的人来说是朝鲜语),它是一个Unicode空格字符,ECMA脚本不会将其解释为空格字符-这意味着它是标识符的有效字符。因此,有三个完全不同的变量,一个是a后面的朝鲜文,一个在a之前,最后一个只有a。为了可读性,将空格替换为_,相同的代码如下所示:

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

查看Mathias变量名验证器的验证。如果这个奇怪的间距真的包含在他们的问题中,我确信这是一个暗示,暗示了这种答案。

不要这样做。认真地

编辑:我注意到(虽然不允许启动变量)变量名称中也允许使用零宽度连接符和零宽度非连接符-请参阅用零宽度字符混淆JavaScript-利弊?。

如下所示:

变量a=1;变量a‍= 2; //一个零宽度字符变量a‍‍= 3; //两个零宽度字符(也可以使用另一个)如果(a==1&a‍==2&&a(&&a)‍‍==3) {console.log(“你好!”)}

我认为这是实现它的最小代码:

i=0,a={valueOf:()=>++i}如果(a==1&&a==2&&a==3){console.log('Mind===Blown');}

创建具有自定义值Of的虚拟对象,该值在每次调用时递增全局变量i。23个字符!

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

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

解决方案说明:

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