Is it ever possible that (a ==1 && a== 2 && a==3) could evaluate to true, in JavaScript?

This is interview question asked by a major tech company. My answer was that it's impossible. They said nothing is impossible. It happened 2 weeks back, but I'm still trying to find the answer. I know we never write such code in our day to day job, but I'm curious.

share|improve this question
6  
Comments are not for extended discussion; this conversation has been moved to chat. – deceze yesterday
6  
This is a fantastic interview question. I've never encountered this one (or one like this one) myself, but this is much better than one I've heard about involving finding loops in linked lists. It's still underhanded and I wouldn't disqualify someone on this question alone, but I'd certainly favor candidates who could recognize that something underhanded might be going on. – Draco18s yesterday
76  
If this is somewhat representative of the kind of code that dwells in that company's codebase … run 💨🏃‍♂️ – FeifanZ yesterday
205  
This is simply awfull interview question... – ghord yesterday
22  
To the people that apparently voted to cloae this as too broad: is that a dig at Javascript, saying that there are too many valid answers? – tomsmeding yesterday

30 Answers 30

up vote 1505 down vote accepted

If you take advantage of how == works, you could simply create an object with a custom toString (or valueOf) function that changes what it returns each time it is used such that it satisfies all three conditions.

const a = {
  i: 1,
  toString: function () {
    return a.i++;
  }
}

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


The reason this works is due to the loose equality operator used. When using loose equality, if one of the operands is of a different type than the other, the engine will attempt to convert one to the other. In the case of an object on the left and a number on the right, it will attempt to convert the object to a number by first calling valueOf if it is callable, and failing that, it will call toString. I used toString in this case simply because it's what came to mind, valueOf would make more sense. If I instead returned a string from toString, the engine would have then attempted to convert the string to a number giving us the same end result, though with a slightly longer path.

share|improve this answer
23  
Could you achieve this by altering the implied valueOf() operation? – Sterling Archer 2 days ago
13  
Yes, valueOf works in place of toString for the same reason – Kevin B 2 days ago
3  
Comments are not for extended discussion; this conversation has been moved to chat. – deceze yesterday
7  
According to this a number conversion will be tried first so valueOf is slightly better. – Salman A yesterday
5  
@Pureferret the left-hand side of the equality comparison is an object, not a number. That that object has a number property on i doesn't bother the engine. ;) – tomsmeding yesterday

I couldn't resist - the other answers are undoubtedly true, but you really can't walk past the following code:

var a = 1;
var a = 2;
var a = 3;
if(aᅠ==1 && a== 2 &&ᅠa==3) {
    console.log("Why hello there!")
}

Note the weird spacing in the if statement (that I copied from your question). It is the half-width Hangul (that's Korean for those not familiar) which is an Unicode space character that is not interpreted by ECMA script as a space character - this means that it is a valid character for an identifier. Therefore there are three completely different variables, one with the Hangul after the a, one with it before and the last one with just a. Replacing the space with _ for readability, the same code would look like this:

var a_ = 1;
var a = 2;
var _a = 3;
if(a_==1 && a== 2 &&_a==3) {
    console.log("Why hello there!")
}

Check out the validation on Mathias' variable name validator. If that weird spacing was actually included in their question, I feel sure that it's a hint for this kind of answer.

Don't do this. Seriously.

share|improve this answer
150  
Judging by the odd spacing in the original question, I think this is EXACTLY the answer the interview question was looking for - exploiting non-space characters that look like spaces. Good spot! – Baracus yesterday
7  
@Baracus It was RonJohn who noticed the weird spacing in his comment on Kevin's answer which reminded me of this (awful) technique, so I can't take credit for spotting it. I was kinda surprised noone had already answered with this though, as it went around my work a few years ago because of a blog post somewhere - I kinda assumed it was pretty common knowledge by now. – Jeff yesterday
43  
Of course, this is banned as a standard loophole, which also applies to interviews. [citation needed] – Sanchises yesterday
23  
Could someone please write an uglifier which uses those space characters for variables. – schmunk yesterday
10  
This knowledge will never provide any value to a company. What a dumb interview question lol. – Edmund Reed 23 hours ago

IT IS POSSIBLE!

var i = 0;

with({
  get a() {
    return ++i;
  }
}) {
  if (a == 1 && a == 2 && a == 3)
    console.log("wohoo");
}

This uses a getter inside of a with statement to let a evaluate to three different values.

... this still does not mean this should be used in real code...

share|improve this answer
28  
Yes I was trying the same thing :) So the correct answer in the interview would be, "It cannot happen in my code because I never use with." – Pointy 2 days ago
2  
@Pointy - And, I program in strict mode where with is not allowed. – jfriend00 2 days ago
2  
@Pointy in the accepted answer they do something similar without the with so it can happen – Jorrit yesterday
1  
@jorrit no one would use ==. And === prevents the accepted answer – Jonas W. yesterday
1  
@JonasW. A lot of people still use == but I haven't seen with since ... well actually never outside of JS documentation where it says "please don't use that". Anyway, a nice solution. – wortwart yesterday

If it is asked if it is possible (not MUST), it can ask "a" to return a random number, it would be true if it generates 1,2 and 3 sequentially.

with({
  get a() {
    return Math.floor(Math.random()*4);
  }
}){
  for(var i=0;i<1000;i++){
    if (a == 1 && a == 2 && a == 3){
      console.log("after "+(i+1)+" trials, it becomes true finally!!!");
      break;
    }
  }
}

share|improve this answer
6  
Horray for --bogosort-- bogogeneration? – Baldrickk yesterday
27  
I would deliberately give this answer even if I knew the other solutions, because it answers the question but is obviously not what they were after. Play stupid games, win stupid prizes. – Edmund Reed 23 hours ago
    
what, the first time i ran the code snippet it said it only took 1 trial – Andrew 6 hours ago

It can be accomplished using the following in the global scope. For nodejs use global instead of window in the code below.

var val = 0;
Object.defineProperty(window, 'a', {
  get: function() {
    return ++val;
  }
});
if (a == 1 && a == 2 && a == 3) {
  console.log('yay');
}

This answer abuses the implicit variables provided by the global scope in the execution context by defining a getter to retrieve the variable.

share|improve this answer
    
This assumes a is a property of this which it does not appear to be. If a was a local variable (which it looks like), then this would not work. – jfriend00 2 days ago
    
@jfriend00 you mean if you placed var a; somewhere? – jontro 2 days ago
    
Yeah. Referencing a == 1 implies than a is a variable somewhere, not a property of this. While there is an oddball place like globals where both could be true, generally, declaring a variable with var a or let a means there's no this that lets you access a as a property like you're code assumes. So, your code is apparently assuming some weird global variable thing. For example, your code does not work in node.js and not in strict mode inside a function. You should specify the exact circumstances where it works and probably explain why it works. Otherwise, it's misleading. – jfriend00 2 days ago
    
@jfriend00 well sure. Not sure that it would add much more value in combination with the other already answers. Will update the answer – jontro 2 days ago
6  
The question was, could this "ever" be true. And the answer is yes, and this is one of the scenarios where it might be true: a is not a local variable and is defined on the global scope with an incrementing getter. – Zac Delventhal 10 hours ago

When you can't do anything without regular expressions:

var a = {
  r: /\d/g, 
  valueOf: function(){
    return this.r.exec(123)[0]
  }
}

if (a == 1 && a == 2 && a == 3) {
    console.log("!")
}

share|improve this answer
5  
Umm.. how does this works? – Abdillah yesterday
11  
@Abdillah a regex object will remember the last index it matches, call exec again will begin searching from that index. MDN is not very clear. – Simon Chan yesterday
    
I see, so the this.r regex object remember the state / index. Thanks! – Abdillah yesterday

This is also possible using a series of self-overwriting getters:

(This is similar to jontro's solution, but doesn't require a counter variable.)

(() => {
	"use strict";
	Object.defineProperty(this, "a", {
		"get": () => {
			Object.defineProperty(this, "a", {
				"get": () => {
					Object.defineProperty(this, "a", {
						"get": () => {
							return 3;
						}
					});
					return 2;
				},
				configurable: true
			});
			return 1;
		},
		configurable: true
	});
	if (a == 1 && a == 2 && a == 3) {
		document.body.append("Yes, it’s possible.");
	}
})();

share|improve this answer
27  
Note that the approach of using a getter also works with ===, not just ==. – Makyen yesterday

Example without getters or valueOf:

a = [1,2,3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3);

This works because == invokes toString which calls .join for Arrays.

Another solution, using Symbol.toPrimitive which is an ES6 equivalent of toString/valueOf:

let a = {[Symbol.toPrimitive]: ((i) => () => ++i) (0)};

console.log(a == 1 && a == 2 && a == 3);

share|improve this answer
    
without valueOf, well... its more indirect but basically the same thing. – Jonas W. 11 hours ago
2  
I really like this solution because you don't override anything but the objects own join function, and it's just a very clean and easy to read hack that makes the logic evaluate to true. – Alex Pedersen 11 hours ago
4  
Honestly I think this is the best answer. It involves nothing out of the ordinary, just setting a few values. Very easy to understand even with basic JS knowledge. Well done. – Zac Delventhal 10 hours ago
1  
This makes so much sense it almost feels useful. – Andrew 6 hours ago
    
I knew most answers would be about abusing toString or valueOf but this one caught me completely out of guard. Very clever and I didn't know it did call .joininternally, but it makes total sense. – GBarroso 9 mins ago

I don't see this answer already posted, so I'll throw this one into the mix too. This is similar to Jeff's answer with the half-width Hangul space.

var a = 1;
var  = 2;
var а = 3;
if(a == 1 &&  == 2 && а == 3) {
    console.log("Why hello there!")
}

You might notice a slight discrepancy with the second one, but the first and third are identical to the naked eye. All 3 are distinct characters:

a - Latin lower case A
- Full Width Latin lower case A
а - Cyrillic lower case A

The generic term for this is "homoglyphs": different unicode characters that look the same. Typically hard to get three that are utterly indistinguishable, but in some cases you can get lucky. A, Α, А, and Ꭺ would work better (Latin-A, Greek Alpha, Cyrillic-A, and Cherokee-A respectively; unfortunately the Greek and Cherokee lower-case letters are too different from the Latin a: α,, and so doesn't help with the above snippet).

There's an entire class of Homoglyph Attacks out there, most commonly in fake domain names (eg. wikipediа.org (Cyrillic) vs wikipedia.org (Latin)), but it can show up in code as well; typically referred to as being underhanded (as mentioned in a comment, [underhanded] questions are now off-topic on PCCG, but used to be a type of challenge where these sorts of things would show up). I used this website to find the homoglyphs used for this answer.

share|improve this answer
4  
"Slight discrepancy" is not how I would call that. – hvd yesterday
    
@hvd Entirely depends on your font rendering. This is what I see. – Draco18s yesterday
    
1  
@Jake Yeah, the Full Width Latin lower case A isn't the greatest homoglyph (but the capital-letter variants are amazing). Generally though you only need two to get the desired effect. – Draco18s yesterday
    
@Draco18s Agreed re: only 2 usually being needed. Good job on the extra info too! – JakeSteam yesterday

Alternatively, you could use a class for it and an instance for the check.

function A() {
    var value = 0;
    this.valueOf = function () { return ++value; };
}

var a = new A;

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

share|improve this answer
    
Gongratulations for your second best answer ;) (another confirmation that votes on SO are completely random) – Jonas W. 11 hours ago
    
@JonasW., the question was a dupe, which does not receive so much attention, but was faily the same. – Nina Scholz 11 hours ago
1  
just function A() {value = 0; at the start? – Dave C 10 hours ago

Rule number one of interviews; never say impossible.

No need for hidden character trickery.

window.__defineGetter__( 'a', function(){
    if(typeof i !== 'number'){
        // define i in the global namespace so that it's not lost after this function runs
        i = 0;
    }
    return ++i;
});

if( a == 1 && a == 2 && a == 3 ){
    alert('Oh dear, what have we done?');
}

share|improve this answer
    
Ouch. __defineGetter__ is actually not part of the js language, just an ugly version of defineProperty. typeof is not a function and this undeclared i is just awful. Still seems to be worth 40 upvotes :/ – Jonas W. 11 hours ago
2  
@JonasW. 41 upvotes :-) I am aware that __defineGetter__ is deprecated per developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… but it clearly executes in my FireFox v 57.0.4 so I opted to show this instead of defineProperty() because legacy code is real and cannot be ignored. Regardless of the ugliness, declaring i in the way I did is a well known/documented behavior. Maybe I was just in a PCG mood ¯\_(ツ)_/¯ – MonkeyZeus 10 hours ago

Honestly though, whether there is a way for it to evaluate to true or not (and as others have shown, there are multiple ways), the answer I'd be looking for, speaking as someone who has conducted hundreds of interviews, would be something along the lines of:

"Well, maybe yes under some weird set of circumstances that aren't immediately obvious to me... but if I encountered this in real code then I would use common debugging techniques to figure out how and why it was doing what it was doing and then immediately refactor the code to avoid that situation... but more importantly: I would absolutely NEVER write that code in the first place because that is the very definition of convoluted code, and I strive to never write convoluted code".

I guess some interviewers would take offense to having what is obviously meant to be a very tricky question called out, but I don't mind developers who have an opinion, especially when they can back it up with reasoned thought and can dovetail my question into a meaningful statement about themselves.

share|improve this answer
1  
So, would you penalize someone who takes your question in good faith, and is so knowledgable that they can actually answer it correctly? I'd be pretty upset if someone did that to me. Not sure whether that's your intent, but if it's not, you might want to edit your answer to make it clear. – Don Hatch yesterday
8  
The question (or all interview questions) is probably to test the candidates willingness to think about a problem, especially ones that are "apparently obvious", like this one. Someone who refuses to think because they believe they "know" the answer is not a good hire. – Shammoo yesterday
1  
@Don Hatch No, I wouldn't penalize them if they answered in good faith and especially if they gave a correct answer like those others have shown... but I would then ask a follow-up to try and probe whether they think it's a good way to write code or not. Being knowledgeable and being able to come up with a "correct" answer is only part of being a good developer. Far more important for a "professional" developer is writing code that is understandable and maintainable down the road, often times by less capable developers. Overly clever developers are pretty much as bad as incapable ones IME. – Frank W. Zammetti 20 hours ago
4  
This doesn't answer the question. – TylerH 11 hours ago
1  
The sad thing about this answer is that a 1rep user answered that yesterday and got 2 downvotes causing him to delete this question. – Jonas W. 11 hours ago

This is possible in case of variable a being accessed by, say 2 web workers through a SharedArrayBuffer as well as some main script. The possibility is low, but it is possible that when the code is compiled to machine code, the web workers update the variable a just in time so the conditions a==1, a==2 and a==3 are satisfied.

This can be an example of race condition in multi-threaded environment provided by web workers and SharedArrayBuffer in JavaScript

share|improve this answer
8  
Honestly, this is the best answer. All the other answer require a deliberate attempt to do something deeply unintuitive. This answer actually reflects something that might happen in the real world - a race condition. – Tom Swirly 17 hours ago
4  
Not only that - I've actually seen this happen in the real world. Not with the exact condition in the question, but certainly with checking (a==1) at the start of a function and (a==2) later in the function, and having code hit both conditions. FYI, the first time I saw this happening was in a car engine controller, and we put coding standards in place. The second time was in a chaff and flare dispenser system for military aircraft, and on my very first day at the company I found this and fixed it, while the rest of the team were still discussing the problem. (Kudos level: high! :) – Graham 13 hours ago

Here's another variation, using an array to pop off whatever values you want.

const a = {
  n: [3,2,1],
  toString: function () {
    return a.n.pop();
  }
}

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

share|improve this answer

Actually the answer to the first part of the question is "Yes" in every programming language. For example, this is in the case of 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;
}
share|improve this answer
14  
I don't think it's possible in every programming language. Not all languages have preprocessors, for example. For that matter, not all languages use && for logical "and". – Keith Thompson yesterday
3  
I found a way that works both in Python and C++ which uses operator overloading. – Donald Duck yesterday
6  
Please do the same in Brainf*ck – Hagen von Eitzen yesterday
4  
And you can do it in Java by using reflection and messing up the integer cache. – CAD97 yesterday
5  
Can't do it in languages that woudn't support mutation in that spot, e.g. nothing comparable is available in haskell – Jason Carr 21 hours ago

Okay, another hack with generators:

const value = function* () {
  let i = 0;
  while(true) yield ++i;
}();

Object.defineProperty(this, 'a', {
  get() {
    return value.next().value;
  }
});

if (a === 1 && a === 2 && a === 3) {
  console.log('yo!');
}
share|improve this answer

Javascript

a == a +1

In Javascript, there are no integers but only Numbers, which are implemented as double precision floating point number.

It means that if a Number a is large enough, it can be considered equal to 3 consecutive integers:

a = 100000000000000000
if (a == a+1 && a == a+2 && a == a+3){
  console.log("Precision loss!");
}

True, it's not exactly what the interviewer asked (it doesn't work with a=0), but it doesn't involve any trick with hidden functions or operator overloading.

Other languages

For reference, there are a==1 && a==2 && a==3 solutions in Ruby and Python. With a slight modification, it's also possible in Java.

Ruby

With a custom ==:

class A
  def ==(o)
    true
  end
end

a = A.new

if a == 1 && a == 2 && a == 3
  puts "Don't do this!"
end

or an increasing a:

def a
  @a ||= 0
  @a += 1
end

if a == 1 && a == 2 && a == 3
  puts "Don't do this!"
end

Python

class A:
    def __eq__(self, who_cares):
        return True
a = A()

if a == 1 and a == 2 and a == 3:
    print("Don't do that!")

Java

It's possible to modify Java Integer cache. They're not primitive ints though, so Integer.valueOf(1) has to be used instead of just 1:

package stackoverflow;

import java.lang.reflect.Field;


public class IntegerMess
{
    public static void main(String[] args) throws Exception {
        Field valueField = Integer.class.getDeclaredField("value");
        valueField.setAccessible(true);
        valueField.setInt(1, valueField.getInt(42));
        valueField.setInt(2, valueField.getInt(42));
        valueField.setInt(3, valueField.getInt(42));
        valueField.setAccessible(false);

        int a = 42;

        if (a == Integer.valueOf(1) && a == Integer.valueOf(2) && a == Integer.valueOf(3)) {
            System.out.println("Bad idea.");
        }
    }
}
share|improve this answer
2  
Code golf SE anyone? – Tsahi Asher 14 hours ago
9  
The question is tagged JS though? – cᴏʟᴅsᴘᴇᴇᴅ 14 hours ago
5  
@cᴏʟᴅsᴘᴇᴇᴅ: Java, Javascript, potayto, potahto :) There are enough good JS answers already. I just thought it would be interesting to show how it can be done in other languages, and possibly give JS developers some ideas. – Eric Duminil 9 hours ago
    
@cᴏʟᴅsᴘᴇᴇᴅ: Updated with a JS example. – Eric Duminil 9 hours ago
    
Hey, that's a cool one. Upvoted! – cᴏʟᴅsᴘᴇᴇᴅ 9 hours ago

Even without confusing naming, overloading, or random variables, a == 1 && a == 2 && a == 3 can return true in multi-threaded environments as the value of a may change between each comparison as long as it is not thread-safe.

share|improve this answer
1  
Unless on node.js, JavaScript should be thread safe, as it's singlethreaded – Cristik yesterday
15  
Node.js is actually single-threaded, so nope. – Iso yesterday
2  
You are correct, of course, but the interviewers did say that nothing is impossible. I just provided an example case where the statement may be true without the code necessarily being written to be confusing. – Rogem 18 hours ago

This one uses the defineProperty with a nice side-effect causing global variable!

var _a = 1

Object.defineProperty(this, "a", {
  "get": () => {
    return _a++;
  },
  configurable: true
});

console.log(a)
console.log(a)
console.log(a)

share|improve this answer
6  
you could use a closure over a: get: (a => () => ++a)(0), no global necessary. – Nina Scholz yesterday
6  
@NinaScholz sure, but we're talking about bad practices here - just let me have this :D – Ben Aubin yesterday

Instead of starting the usual JavaScript bashing, everyone just wait a minute and think about whether this is a problem of the JavaScript language as such.

In fact, all of this boils down to on of the following kinds of issues:

  1. Encoding: Intentionally messing around with Unicode using homoglyphs or space characters. But be aware: A more subtle version of this kind of issue can be introduced when copy & pasting code from the Web that contains unexpected Unicode code points (e.g. because a content management system replaced fl with Unicode 'LATIN SMALL LIGATURE FL' (U+FB02)).
  2. Multi-threading: A hard to produce race-condition. In JavaScript this would only be possible when using Web Workers.
  3. Side-effects: A side-effect of the equality comparison operation (which doesn't have to be as obvious as in the examples here, often side-effects are very subtle).

These kind of issues can appear in many programming languages, not only JavaScript, so we aren't seeing one of the classical JavaScript WTFs here. For example, you can find an example in a totally different programming language (C#) exhibiting a side-effect (an obvious one) here.

Of course, the interview question and the samples here all look very retrieved. But they are a good reminder that

  • Side-effects can get really nasty and that a well-designed program should be free from unwanted side-effects.
  • Multi-threading and mutable state can be problematic.
  • Not doing character encoding and string processing right can lead to nasty bugs.
share|improve this answer
10  
This answer doesn't make sense, I would not really want to come to a JS question to see a c# answer. – cᴏʟᴅsᴘᴇᴇᴅ 14 hours ago
7  
@cᴏʟᴅsᴘᴇᴇᴅ: As explained in my answer, the problem is language agnostic. One might argue that is shouldn't have a javascript tag at all. – Dirk Vollmar 12 hours ago
1  
Then, the question becomes way too broad. Different languages can implement this with varying degrees of ease. The question has gained so much traction because it is a JS specific Q&A, but that's just my 2c. – cᴏʟᴅsᴘᴇᴇᴅ 12 hours ago
1  
the causes are different C# and javascript so this answer is not legit. – Edwin 12 hours ago
3  
@Edwin: The causes are exactly the same: Unicode fiddling with similar-looking glyphs or space characters, race conditions, or side-effects of the comparison operation (the latter being shown in my example). – Dirk Vollmar 12 hours ago

An ES6 answer that makes use of Symbols:

const a = {value: 1};
a[Symbol.toPrimitive] = function() { return this.value++ };
console.log((a == 1 && a == 2 && a == 3));
share|improve this answer

Same, but different, but still same (can be "tested" multiple times):

const a = { valueOf: () => this.n = (this.n || 0) % 3 + 1}
    
if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

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

My idea started from how Number object type equation works.

share|improve this answer

getMilliseconds() can also do that: by forcing a == 1, a == 2 and a == 3 finishes execution at different time in terms of milliseconds:

with({
  get a() {
    var s=new Date().getMilliseconds();
    while(s===new Date().getMilliseconds()){
    }
    console.log('1+s%3='+(1+s%3));
    return 1+s%3;
  }
}){
  if (a == 1 && a == 2 && a == 3){
    console.log('It becomes true');
  }
}

Notes: this script may needs to retry few times, until 1+s%3 starts at 1, and then 2 and finally 3.If success, it would print something like:

1+s%3=1
1+s%3=2
1+s%3=3
It becomes true

The while loop is used to ensure the value of millisecond changes before next time execution.

share|improve this answer

if you are allowed to reverse numbers and variables, the trick can be done with valueOf:

var i = 0
var a = {i: 0, valueOf: () => ++ i}
1 == a && 2 == a && 3 == a
// => true

share|improve this answer
4  
this is actually not an aswer.. should have been posted to comment. Where so brilliant answers are already available, why to post this. – undefined yesterday
2  
@undefined Ok, perhaps a comment and not an answer. But I used a different technique than that brilliant answers. So this post was just to complete the techniques to achive that strange behaviour – afx yesterday
1  
Reversing numbers and variables isn't necessary here. a==1 && a==2 && a==3 is true as well. And valueOf was already exploited in the same way in earlier answers (e.g. answer by Nina Scholz) – default locale 23 hours ago
1  
You have two is. Did you originally mean to use valueOf: function() { return ++this.i; }? – Neil 16 hours ago
    
@undefined that applies to every answer except the first 5 :/ – Jonas W. 11 hours ago

This is also possible in Rust, see it live:

struct A();
impl PartialEq<i32> for A {
    fn eq(&self, _other: &i32) -> bool {
        true
    }
}
fn main() {
    let a = A();
    assert!(a == 1 && a == 2 && a == 3);
}
share|improve this answer
10  
The question is asking about JavaScript, not Rust. – cpburnz 12 hours ago

In reference to Eric Duminil's Java approach, here is an example for Java that does not need to change the original questions syntax by provoking a race condition.

public class IntegerMess
{
    public static class Worker implements Runnable {
        private int n;
        public Worker(int n){ this.n=n; }
        public void run() { while(true) IntegerMess.a = n; }
    }

    public static volatile int a=1;

    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        for (int i = 1; i <= 3; i++) {
            Runnable worker = new Worker(i);
            executor.execute(worker);
        }

        long spins = 0;
        while(true){
            spins++;
            if (a == 1 && a == 2 && a == 3) {
                System.out.println("I finally came to rest after "+spins+" spins");
                System.exit(0);
            }
        }
    }
} 
share|improve this answer
11  
The question is asking about JavaScript, not Java. – cpburnz 12 hours ago
    
@cpburnzc I think they are very similar because of their names. Source: every tech recruiter ever. – user1717828 1 hour ago

in these code all of 3 "a" are different


the first "a" (var aᅠ = 1;) has char code

'aᅠ'.charCodeAt(0) -> 97

'aᅠ'.charCodeAt(1) -> 65440


the second one "a" (var a = 2;)

'a'.charCodeAt(0) -> 97

'a'.charCodeAt(1) -> NaN


and the third one "ᅠa" (var ᅠa = 3;)

'ᅠa'.charCodeAt(0) -> 65440

'ᅠa'.charCodeAt(1) -> 97


so we have 3 different variables!!!

share|improve this answer

let i = 0;

function a() {
}

a.toString = function () {
  return ++i;
};

if (a == 1 && a == 2 && a == 3) {
  console.log('You did not mean to get here, did you?');
}

share|improve this answer
    
I'm curious to know how this differs from the accepted answer, besides i++ being different from ++i. Could you explain please? – cᴏʟᴅsᴘᴇᴇᴅ 9 hours ago
1  
Function vs Object, IMHO. Though I just realize after your comment that functions are indeed instanceof Object in JS. – dopeddude 9 hours ago
6  
This is just a duplicate of the accepted answer but without any explanation. – ndugger 8 hours ago

By overwriting the "=="-operator for integers it can easily achieved.

share|improve this answer
2  
Can you provide some example code? – kalabalik 13 hours ago
6  
You cannot overload the == operator, or any other operator in JavaScript. – cpburnz 12 hours ago
    
one could, given one writes its own V8 – Felipe Valdes 2 hours ago

It's possible in every single language that supports method overloading. Say, in Python, the a == b operator just stands for a.__eq__(b) call. So, once you override that method, any side effect may occur comparing objects. Here is a small example:

class A:
    def __init__(self, a):
        self.a = a
    def __eq__(self, b):
        self.a += 1
        return self.a == b

a = A(0)

a == 1 and a == 2 and a == 3
>>> True

Needless to say, that's impossible in those languages that provide immutable data structures.

share|improve this answer
3  
The question is asking about JavaScript, not Python, which is key to the question because JavaScript does not support operator overloading. – cpburnz 7 hours ago

protected by Community yesterday

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.