반응형

캔 (A == 1 && a == 2 && a == 3) 이제까지 진실로 평가할 수 있습니까?


질문

 

사회자 참고 : 코드를 편집 하거나이 알림을 제거하는 충동에 저항하십시오.공백의 패턴은 질문의 일부일 수 있으므로 불필요하게 변조해서는 안됩니다."공백이 중요하지 않은"캠프에있는 경우 코드를 수락 할 수 있어야합니다.

(== 1 && a == 2 && a == 3) 자바 스크립트에서 true로 평가할 수 있습니까?

이것은 주요 기술 회사가 묻는 인터뷰 문제입니다.그것은 2 주 후에 일어났지 만, 나는 아직도 대답을 찾으려고 노력하고 있습니다.나는 우리가 일상적인 일에 그러한 코드를 쓰지 않는다는 것을 알고 있지만, 나는 호기심이 많습니다.


답변

 

== 작동 방식을 활용하면 세 가지 조건을 모두 만족 시키도록 사용되는 매번 반환하는 내용을 변경하는 사용자 지정 ToString (또는 ValueOf) 함수가있는 객체를 만드는 것만으로 만듭니다.

const a = { I : 1, toString : 함수 () { 반환 A.I ++; } } if (a == 1 & == 2 && a == 3) { console.log ( 'Hello World!'); }


이 작품이 작품의 이유는 느슨한 평등 연산자의 사용으로 인한 것입니다.느슨한 평등을 사용할 때 피연산자 중 하나가 다른 유형과 다른 유형이면 엔진이 하나를 다른 것으로 변환하려고 시도합니다.오른쪽의 왼쪽 및 숫자의 객체의 경우, 호출 할 수있는 경우 첫 번째 호출을함으로써 숫자를 숫자로 변환하려고 시도하고 toString이라고합니다.나는이 경우에 tostring을 사용했기 때문에 valueof가 더 의미가 있기 때문입니다.대신 ToString에서 문자열을 반환하면 엔진이 약간 더 긴 경로로 우리에게 동일한 최종 결과를주는 숫자로 문자열을 변환하려고 시도했습니다.



답변

나는 저항 할 수 없었습니다. 다른 답변은 의심의 여지없이 사실이지만 다음 코드를 지나갈 수는 없습니다.

var a ㅤ = 1; var a = 2; var ㅤ a = 3; if (a ㅤ == 1 && a == 2 && o == 3) { console.log ( "왜 안녕하세요!") }

if 문장에서 이상한 간격 (귀하의 질문에서 복사 된).공백 문자로 ECMA 스크립트로 해석되지 않는 유니 코드 공간 문자 인 반쯤 너비 한글 (익숙하지 않은 사람들에게는 한국어)입니다. 즉, 식별자의 유효한 문자임을 의미합니다.그러므로 3 개의 완전히 다른 변수가 있습니다. 한글 뒤에는 A, 하나가 이전과 마지막 것만으로 만드는 것입니다._로 공간을 _로 교체 할 수 있도록, 동일한 코드는 다음과 같습니다.

var a_ = 1; var a = 2; var _a = 3; if (a _ == 1 && a == 2 && _ a == 3) { console.log ( "왜 안녕하세요!") }

Mathias '변수 이름 유효성 검사기에서 유효성 검사를 확인하십시오.그 이상한 간격이 실제로 그들의 질문에 포함되어 있다면, 나는 그것이이 종류의 답변을 힌트라고 확신합니다.

이것을하지 마십시오.진지하게.

편집 : 그것은 (변수를 시작할 수는 없지만) 제로 너비의 조이너와 0- 너비가 아닌 가입자 문자가 변수 이름에서 허용됩니다 - 찬사와 단점?.

이것은 다음과 같습니다.

var a = 1; var a = 2;// 하나의 너비가 하나의 문자입니다 var a = 3;// 두 개의 제로 너비 문자 (또는 다른 하나를 사용할 수 있습니다) if (a == 1 & == 2 && a == 3) { console.log ( "왜 안녕하세요!") }



답변

것이 가능하다!

var i = 0; 와 함께({ 도착() { Return ++ i; } }) { if (a == 1 && a == 2 && a == 3) console.log ( "wohoo"); }

이것은 A와 함께 Getter를 사용하여 세 가지 값으로 평가할 수 있습니다.

... 이것은 여전히 이것이 실제 코드에서 사용되어야한다는 것을 의미하지는 않습니다 ...

더 나쁜이 트릭은 ===의 사용과 함께 작동합니다.

var i = 0; 와 함께({ 도착() { Return ++ i; } }) { if (a! == a) console.log ( "yep, 이것은 인쇄됩니다."); }



답변

getter 또는 ValueOf가없는 예제 :

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

==는 tostring을 호출하는 tostring을 호출하기 때문에이 작업이 작동합니다.

ToString / ValueOf의 ES6 등가물 인 Symbol.Toprimitive를 사용하는 또 다른 해결책 :

i = 0; a = {[symbol.toprimitive] : () => ++ i}를 봅시다. console.log (a == 1 && a == 2 && a == 3);



답변

가능한지 묻는 경우 (필수가 아님), 임의의 숫자를 반환하려면 "a"를 묻는 메시지가 표시 될 수 있습니다.1, 2, 3을 순차적으로 생성하면 사실이 될 것입니다.

와 함께({ 도착() { 반환 math.floor (math.random () * 4); } }) { for (var i = 0; i <1000; i ++) { if (a == 1 & == 2 && a == 3) { console.log ( "후"+ (i + 1) + "시험, 마침내 사실이됩니다!"); 부서지다; } } }



답변

정규 표현식 없이는 아무 것도 할 수 없을 때 :

var a = { r : / \ d / g, ValueOf : 함수 () { return this.exec (123) [0] } } if (a == 1 & == 2 && a == 3) { console.log ( "!") }

그것은 프리미티브 (예 : 숫자)와 비교하여 객체가 호출되는 사용자 정의 ValueOf 메서드로 인해 작동합니다.메인 트릭은 A.ValueOf가 G LAF가있는 정규 표현식에서 EXEC에서 exec을 호출하기 때문에 새로운 값을 반환합니다. 이는 G가 일치하는 모든 일치가 발견되는 LastIndex를 업데이트합니다.그래서 처음에는 this.r.lastindex == 0, 1 일치하고 lastIndex를 업데이트합니다. this.r.lastIndex == 1 다음에 regex는 2 등등을 일치합니다.

출처:https://stackoverflow.com/questions/48270127/can-a-1-a-2-a-3-ever-evaluate-to-true
반응형