할 수 있는(a==1&&==2&&==3)적 true?

**자 참고:*****주시기 바랍에 저항을 촉구하는 코드를 편집하거나 제거할 수 있도록 해줍니다. 패턴의 공백의 일부가 될 수 있습니다 질문에 따라서 해야 되지 않을 훼손하고 있습니다. 에 있다면"공백지 않"캠프,당신을 받아들일 수 있는 코드 같은 것입니다.

그것은 이제까지 가능한(a==1&&==2&&==3)을 평가할 수 있었을true에서 JavaScript?

이 인터뷰의 질문에 주요 기술 회사입니다. 이 일이 두 가지 주지만,나는'm 여전히 노력하고 답을 찾을 수 있습니다. 내가 알고 있는 우리가 결코 그러한 코드를 작성에서 우리의 일상적 작업,그러나 나는'm 궁금합니다.

질문에 대한 의견 (17)
해결책

를 활용하면어떻게==works간단히 수행할 수 있습을 만들 개체가 가진 사용자 정의toString(또는valueOf)함수는 변화는 무엇인가 반환 각 시간에 사용되는 것과 같은이 모두 만족하는 세 가지 조건.

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

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

이 작품의 사용으로 인해 느슨한 평등을 연산자입니다. 을 사용할 때 느슨한 평등을 하는 경우 하나의 피연산자는 다른 유형의 다른 것보다,엔진으로 변환하려고 시도 하다. 의 경우에는 개체의 왼쪽에서 많이 오른쪽에,그것은 개체를 변환하려고 시도하는 숫자에 의해 처음 호출valueOf는 경우 이 호출로,그리고 실패하는 것입니다전화 toString. 내가 사용하는toString이 경우에는 간단하기 때문에 그것이's 무엇을 마음에 와서,valueOf는 것을 더 의미가 있습니다. 면 내 대신 돌아에서 문자열toString,엔진의 것 다음을 변환할 문자열을 수는 동일한 최종 결과는,하지만 약간 더 긴 경로입니다.

해설 (19)

나't 저항하는 다른 대답은 의심 할 여지없이 사실이지만,당신은 정말 수 있't 과거 산책는 다음 코드:

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

참고 이상한 간격에서만약에진술서(내가 복사에서 당신의 질문에). 그것은 반글(는's 한국어에 익숙하지 않은 사람들을 위해)는 유니코드 문자 공간 구조화되지 않은 ECMA 스크립트로 공백 문자-즉 그것은 유효한 문자에 대한 식별자입니다. 따라서 세 개의 완전히 다른 변수와 하나가 한글 후,그것으로 하나기 전에 마지막 하나만으로. 대체하는 공간으로_가독성을 위해 동일한 코드를 다음과 같이 보일 것입니다.

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

유효성 검사에 Mathias'변수 이름 validator. 만약 그 이상한 간격이었고 실제로에 포함된 자신의 질문에,나는 느낌을 확인하는's 에 대한 힌트를 이 종류의 대답이다.

Don't 니다. 심각합니다.

편집:그것을(지 않지만 시작할 수 있는 변수)이제로 폭 소목제로 폭 non-소목자 또한 허용되는 변수 이름에 볼난독 처리 JavaScript 제로 폭이 문자가-장점과 단점?.

이것은 다음과 같습니다:

var a= 1;
var a‍= 2; //one zero-width character
var a‍‍= 3; //two zero-width characters (or you can use the other one)
if(a==1&&a‍==2&&a‍‍==3) {
    console.log("Why hello there!")
}
해설 (13)

그것이 가능합니다!

var i = 0;

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

이용 getter 내부의함께문 leta평가는 세 가지 다른 값입니다.

...이것은 아직도 의미하지 않는 이에 사용되어야 하는 실제 코드...

더 악화,이 트릭은 또한 작업으로의 사용===.

  var i = 0;

  with({
    get a() {
      return ++i;
    }
  }) {
    if (a !== a)
      console.log("yep, this is printed.");
  }
해설 (12)

예고 없이 필요한 것입 또는 valueOf:

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

이 작품이기 때문에==호출toString호출.가입을 위해배열입니다.

다른 솔루션을 사용하여,기호입니다.toPrimitive는 ES6 에 해당의toString/valueOf:

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

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

요구되는 경우에 가능한 경우(지),그 요청할 수 있"a"를 반환하고 무료로 액세스 할 수 있습니다. 그것은 사실이 될 것 이라고 생성하는 경우 1,2,3 순차적으로 동작한다.


with({
  get a() {
    return Math.floor(Math.random()*4);
  }
}){
  for(var i=0;i
해설 (5)

할 수 있을 때't 없이는 아무것도 할 수있는 regular expressions:

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

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

그것은 작동하기 때문에 사용자 지정valueOf는 방법이라고 할 때 개체에 비해 기본(번호와 같은). 주요 트릭은a.valueOf반환하는 새로운 값을 매기 때문에 그것이's callingexec에 정규 표현식을 가진g깃발하는 원인이 업데이트lastIndex의 정규 표현식의 모든 시간에 맞는 사람을 찾을 수 있습니다. 그래서 처음이다.r.lastIndex==0일치하는1,업데이트lastIndex:이다.r.lastIndex==1,그 다음에 일치 정규식2등이 있습니다.

해설 (4)

이것이 가능한 경우에는 변수의a액세스하여 말,2 웹사자를 통해 SharedArrayBuffer 뿐만 아니라 일부 주 스크립트입니다. 가능성은 낮지만,그것은 가능한 경우 코드를 컴파일하는 컴퓨터 코드 웹 노동자 업데이트 변수그냥 시간에 너무 조건을a==1,a==2==3만족하고 있습니다.

이 예제의 경쟁 조건에서 멀티 스레드 환경을 제공하여 웹자 SharedArrayBuffer 에서 JavaScript.

여기에는 기본적인 구현을 위:

main.js

// Main Thread

const worker = new Worker('worker.js')
const modifiers = [new Worker('modifier.js'), new Worker('modifier.js')] // Let's use 2 workers
const sab = new SharedArrayBuffer(1)

modifiers.forEach(m => m.postMessage(sab))
worker.postMessage(sab)

worker.js

let array

Object.defineProperty(self, 'a', {
  get() {
    return array[0]
  }
});

addEventListener('message', ({data}) => {
    array = new Uint8Array(data)
    let count = 0
    do {
        var res = a == 1 && a == 2 && a == 3
        ++count
    } while(res == false) // just for clarity. !res is fine
    console.log(`It happened after ${count} iterations`)
    console.log('You should\'ve never seen this')
})

modifier.js

addEventListener('message' , ({data}) => {
    setInterval( () => {
        new Uint8Array(data)[0] = Math.floor(Math.random()*3) + 1
    })
})

내 맥북 에어,그것은 발생한 후에 약 10 억의 반복이 첫 번째 시도에서:

두 번째 시도:

로 내가 말했다,가능성이 낮을 것이다,하지만 충분한 시간이 주어진,그것이'll hit 조건이 있습니다.

팁:너무 오래 걸리는 경우에 당신의 시스템입니다. 시에만a==1&&==2변화의 수학.random()*3에서수학이다.random()*2. 더를 추가하고 목록을 삭제합의 기회를 치는 것이다.

해설 (17)

그것을 사용하여 수행할 수 있습 다음 글로벌 범위가 있습니다. 위해및 라이브러리사용글로벌대신에창의코드 아래에 있다.

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

이 대답은 남용을 암시적 변수를 제공한 글로벌 범위에서 실행 컨텍스트를 정의하여 getter 를 검색하는 변수입니다.

해설 (6)

이것은 또한 가능하의 시리즈를 사용하여 자기를 덮어쓰 getters:

(이것은 비슷한 jontro's 솔루션이지만,지 않't 필요로운 변수가 있습니다.)

(() => {
    "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.");
    }
})();
해설 (5)

또는,당신은 클래스를 사용하여 그것을 위해 인스턴스에 대한 확인합니다.

능(){ var value=0; 다.valueOf=function(){return++value;}; }

var a = new A;

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

편집

사용 ES6 클래스는 다음과 같이 보일 것이다

class A {
  constructor() {
    this.value = 0;
    this.valueOf();
  }
  valueOf() {
    return this.value++;
  };
}

let a = new A;

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

I don't 이 대답이 이미 게재,그래서 나는'll throw 이 중 하나로습니다. 이것은 비슷한[Jeff's답변과 함께 반 폭 한글 공간입니다.

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

알 수 있습니다 약간의 차이로 두 번째는,하지만 첫 번째와 세번째 동일한 육안으로 볼 수 있습니다. 모두 3 는 뚜렷한 캐릭터:

a라틴 낮은 경우 -전체 폭 Latin 낮은 경우 а-Cyrillic 낮은 경우

한 일반적인 용어이"homoglyphs":다른 유니코드 문자를 보이는 동일합니다. 일반적으로 어렵는 완전히 구별할 수 있지만,당신이 얻을 수있는 경우 운이 좋다. A Α,А 및 Ꭺ 잘 작동할 것이라는 점을(라틴-A,Greek Alpha,키릴-A,그리고체로키-A입니다,불행히도 그리스어와 체로키 lower-case letters 는 너무 다른 라틴어에서a:α,,그리고는't 도움으로 위의 조각).

이's 의 전체 클래스 Homoglyph 공격을 밖에서 가장 일반적으로 가짜 도메인 이름을(예를 들어.wikipedia.org(Cyrillic)vswikipedia.org(라)),그러나 그것을 보여줄 수 있습에 코드뿐만 아니라 일반적으로 지칭되는 것으로는 불공정(으로 언급에서 의견,[불공정]질문은 이제 그만-주제에PPCG, 그러나 될하는 데 사용되는 종류의 도전하는 이러한 종류의 것들을 표시). 내가 사용하는 이 웹사이트](https://www.irongeek.com/homoglyph-attack-generator.php)을 찾 homoglyphs 사용을 위한이 대답합니다.

해설 (5)

네,그것이 가능합니다! 😎

»JavaScript

if‌=()=>!0;
var a = 9;

if‌(a==1 && a== 2 && a==3)
{
    document.write("<h1>Yes, it is possible!😎</h1>")
}

위의 코드는 짧은 버전(덕분에@Forivin 그 주에 설명)및 다음 코드는 원래:

var a = 9;

if‌(a==1 && a== 2 && a==3)
{
    //console.log("Yes, it is possible!😎")
    document.write("<h1>Yes, it is possible!😎</h1>")
}

//--------------------------------------------

function if‌(){return true;}

는 경우에 당신은 그냥 보는 상단면의 내 코드와 실행 그것은 당신이 말하는 WOW,어떻게 해야 하나요?

그래서 저는 생각은 충분히 말네,그것이 가능하는 사람을 말 신:아무것도 불가능

트:사용 숨겨진 후 문자는만약에만드는 기능이 그것의 이름은 비슷한if. 에서 JavaScript 우리는 무시할 수 없습 그래서 저는 키워드를 사용하도록 강제 이 방법입니다. 그것은 가짜if지만,그것은 작품이 경우에 당신을 위해!


»C#

또한 내가 쓴 C#버전(으로 증가하는 속성 값이 기술):

static int _a;
public static int a => ++_a;

public static void Main()
{
    if(a==1 && a==2 && a==3)
    {
        Console.WriteLine("Yes, it is possible!😎");
    }
}

Live Demo

해설 (14)

JavaScript

a==+1

자바스크립트에서 없정수만`수의 구현되는 등 두 개의 정밀 부동 소수점 숫자입니다.

그것이 의미하는 경우에 숫자충분히 큰 것으로 간주 될 수 있습 같은 세 개의 연속된 정수:

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

True,it's 지 정확히 어떤 면접관이 물었음(그't 작품으로a=0),그't 포함한 어떠한 속으로 숨겨진 기능이나 운영자 합니다.

다른 언어

에 대한 참조가 있a==1&&==2&&==3솔루션 Ruby,Python. 약간의 변형,그's 에서도 가능하 Java.

Ruby

사용자 정의==:

class A
  def ==(o)
    true
  end
end

a = A.new

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

또는 증가하는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 를 수정할 수 Java정수캐시:

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);

        Integer a = 42;

        if (a.equals(1) && a.equals(2) && a.equals(3)) {
            System.out.println("Bad idea.");
        }
    }
}
해설 (10)

이것은 거꾸로 버전[@Jeff's답변*어디에 숨겨진 문자(U+115F,U+1160 또는 U+3164)를 만드는 데 사용되는 변수 처럼 보이는1,23.

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

*는 대답을 간소화할 수 있습니다 사용하여 제로 폭 non-소목(U+200℃)과 영 폭 소목(U+200D). 이러한 두 문자를 사용할 수 있습니다 내 식별자 하지만 시작 부분에서:

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

/****
var a = 1;
var a\u200c = 2;
var a\u200d = 3;
console.log(a == 1 && a\u200c == 2 && a\u200d == 3);
****/

다른 사용 가능하며 동일한 아이디어를 사용하여 예를 들어 유니코드 변형을 선택기를 만들 변수는 똑같(a︀=1;a︁=2;a︀==1&&a︁==2;//true).

해설 (0)

규칙의 인터뷰에게도 말하지 않을 것을 불가능하다.

가 필요없 숨겨진 문자 문제가 있었어요.

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?' );
}
해설 (2)

정직하지만,이 있는지 여부에 대한 방법 평가를 진실하다(그리고 다른 사람으로는 다음과 같이 여러 개 있는 방법)에 대답'd 있고,말하는 사람으로 실시한 수백 개의 인터뷰가 뭔가 될 것인:

"만,어쩌면 아래에서 예상한 상황에서는't 즉시 분명하다 그러나는 경우가 발생하이에서 실제 코드는 다음 사용하는 것이 일반적인 디버깅 기술을 어떻게 그리고 왜 더욱 쉽게 확인할 수 있게 되었습니다 무엇을 더욱 쉽게 확인할 수 있게 되었습니다 그리고 즉시 코드를 리팩터링을 피하는 상황이다...그러나 더 중요한 것:내가 절대적으로 절대 쓰는 코드에서는 첫 번째 장소이기 때문에 매우 정의는 복잡한 코드,그리고 내가 노력하기를 쓰지 않는 복잡한 코드를".

나는 몇 가지 인터뷰는 것을 범죄하는 것은 의미가 분명 매우 까다로운 질문이라는,그러나 나는't 마음이 있는 개발자는 의견을 때,특히 그들은 그 권고 생각할 수 있습 dovetail 나의 질문으로 의미 있는 문의에 대해 자체.

해설 (13)

만약 당신이 이러한 면접 질문(또는 몇 가지 동일하게 예기치 않은 동작하는 코드)에 대해 생각 어떤 종류의 것을 발생시킬 수 있는 행동을 보이는 불가능한에서 먼저 눈:

  1. Encoding이 경우는 변수에서 찾고 있는지 생각합니다. 이 경우 발생할 수 있습니다 당신이 의도적으로 혼란을 주위 유니코드를 사용하여[homoglyphs](https://en.wikipedia.org/wiki/Homoglyph#Unicode_homoglyphs 다)또는[공백 문자](https://stackoverflow.com/a/48274520/40347 용)변수의 이름처럼 또 다른 하나지만,인코딩이 문제가 될 수도 있습을 소개 실수로,예를 들어 복사할 때&붙여넣기 코드에서 웹을 포함하는 예상치 못한 유니코드 포인트(예를 들어 콘텐츠 관리 시스템을 어떤"auto-포맷"와 같은 교체fl유니코드'LATIN 작은 합자 FL'(U+FB02)).

  2. 레이스:A경주-상태가 발생할 수 있습,즉 상황에 코드를 실행하지 않아 순서에 의해 예상합니다. 경쟁 조건을 자주에서 일어나는 멀티스레드 코드,하지만 여러 스레드가 아닌 요구 사항에 대한 경쟁 조건을 가능–asynchronicity 가 충분한(그리고 don't 혼란스러워비동기를 의미하지 않는 여러 쓰레드가 사용 후드).

참고 따라서 자바스크립트에서 무료로하지 않 경쟁 조건 때문에 그것은 하나의 스레드. 시기](https://medium.com/@slavik57/async-race-conditions-in-javascript-526f6ed80665)에 대한 간단한 하나의 스레드–그러나 비동기 예입니다. 의 컨텍스트에서 단 하나 문장의 경쟁 상태는 오히려 하에서 JavaScript.

JavaScript 웹 작업자와 조금 다르다,당신이 할 수 있는 여러 쓰레드. @mehulmpt 는 다음과 같은 우리에게 큰증명의 개념을 사용하여 웹자.

  1. Side-effects:의 부작용은 평등을 비교 작업(지 않는't 있으로 명백한 예제에서 여기에 자주,부작용은 매우 미묘한).

이러한 종류의 문제에 나타날 수 있습니다 많은 프로그래밍 언어,뿐만 아니라 자바스크립트,그래서 우리는't 을 보고 하나의 클래식[JavaScript WTFs](https://github.com/denysdovhan/wtfjs 다)여기1.

물론,인터뷰 질의 및 샘플 여기 모두 매우 고안된다. 하지만 그들은 좋은 것을 알림:

-부작용을 얻을 수 있습니다 정말 불쾌하고는 잘 설계된 프로그램에서 무료로 쓸모 없는 부작용이 나타납니다. -멀티-스레딩 및 변경 가능한 상태에 문제가 될 수 있습니다. -를 하지 않는 문자 인코딩을 가정하고 바로 이어질 수 있는 불쾌한다.

1예를 들어,당신은 예를 찾을 수 있습에서 완전히 다른 프로그래밍 언어(C#)을 전시한 부작용(는 명백한 것)여기.</하위>

해설 (10)

여기's 이 다른 변형,배열을 사용하면 팝업 당신이 원하는 값을.

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

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

좋아요,또 다른 해킹으로 발전기:

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!');
}
해설 (1)

를 사용하여프록시:

var a = new Proxy({ i: 0 }, {
    get: (target, name) => name === Symbol.toPrimitive ? () => ++target.i : target[name],
});
console.log(a == 1 && a == 2 && a == 3);

프록시 기본적으로 척 목표 대상(첫 번째 매개 변수)지만,차단 작업에 대상 물체(이 경우,"제"작업)에 있도록 할 수 있는 기회를 다른 것보다 기본 개체 행동입니다. 이 경우,"제"행동이라고에서a==강제 유형과 비교하기 위해 각각의 번호입니다. 이런 일:

  1. 우리 대상을 만들체,{i:0}에는i시리 카운터
  2. 우리가 만들에 대한 프록시 대상체 및 할당a
  3. 에 대한 각각의a==비교,a's 형식으로 변환된 기본값
  4. 이중 결과를 호출에는a[징이다.toPrimitive]()내부적으로
  5. 프록시 차단을 받고는`a[징이다.toPrimitive]기능을 사용하면"얻을 처리기"
  6. 프록시는's"얻을 처리기"는지 확인합되는 재산을 받은기호입니다.toPrimitive는 경우에 그것은 단위로 반환합 카운터에서 대상 목표:++대상입니다.i. 는 경우 다른 속성이 검색되,우리는 그냥 가을 다시 돌려보내는 기본 속성 값,대상[name]

그래서:

var a = ...; // a.valueOf == target.i == 0
a == 1 && // a == ++target.i == 1
a == 2 && // a == ++target.i == 2
a == 3    // a == ++target.i == 3

으로 대부분의 다른 답변,이와 동등성 검사(==),기 때문에 엄격한 평등사(===)하지 않는 입력 강제 프록시을 가로챌 수 있습니다.

해설 (1)