**자 참고:*****주시기 바랍에 저항을 촉구하는 코드를 편집하거나 제거할 수 있도록 해줍니다. 패턴의 공백의 일부가 될 수 있습니다 질문에 따라서 해야 되지 않을 훼손하고 있습니다. 에 있다면"공백지 않"캠프,당신을 받아들일 수 있는 코드 같은 것입니다.
그것은 이제까지 가능한(a==1&&==2&&==3)
을 평가할 수 있었을true
에서 JavaScript?
이 인터뷰의 질문에 주요 기술 회사입니다. 이 일이 두 가지 주지만,나는'm 여전히 노력하고 답을 찾을 수 있습니다. 내가 알고 있는 우리가 결코 그러한 코드를 작성에서 우리의 일상적 작업,그러나 나는'm 궁금합니다.
를 활용하면어떻게==
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
,엔진의 것 다음을 변환할 문자열을 수는 동일한 최종 결과는,하지만 약간 더 긴 경로입니다.
나'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!")
}
그것이 가능합니다!
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.");
}
예고 없이 필요한 것입 또는 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);
요구되는 경우에 가능한 경우(지),그 요청할 수 있"a"를 반환하고 무료로 액세스 할 수 있습니다. 그것은 사실이 될 것 이라고 생성하는 경우 1,2,3 순차적으로 동작한다.
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;
}
}
}
할 수 있을 때'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
등이 있습니다.
이것이 가능한 경우에는 변수의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
. 더를 추가하고 목록을 삭제합의 기회를 치는 것이다.
그것을 사용하여 수행할 수 있습 다음 글로벌 범위가 있습니다. 위해및 라이브러리
사용글로벌
대신에창의
코드 아래에 있다.
var val = 0;
Object.defineProperty(window, 'a', {
get: function() {
return ++val;
}
});
if (a == 1 && a == 2 && a == 3) {
console.log('yay');
}
이 대답은 남용을 암시적 변수를 제공한 글로벌 범위에서 실행 컨텍스트를 정의하여 getter 를 검색하는 변수입니다.
이것은 또한 가능하의 시리즈를 사용하여 자기를 덮어쓰 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.");
}
})();
또는,당신은 클래스를 사용하여 그것을 위해 인스턴스에 대한 확인합니다.
능(){ 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!');
}
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
라틴 낮은 경우
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 사용을 위한이 대답합니다.
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#버전(으로 증가하는 속성 값이 기술):
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!😎");
}
}
자바스크립트에서 없정수만`수의 구현되는 등 두 개의 정밀 부동 소수점 숫자입니다.
그것이 의미하는 경우에 숫자는
충분히 큰 것으로 간주 될 수 있습 같은 세 개의 연속된 정수:
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.
사용자 정의==
:
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
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!")
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.");
}
}
}
이것은 거꾸로 버전[@Jeff's답변*어디에 숨겨진 문자(U+115F,U+1160 또는 U+3164)를 만드는 데 사용되는 변수 처럼 보이는1
,2
과3
.
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
).
규칙의 인터뷰에게도 말하지 않을 것을 불가능하다.
가 필요없 숨겨진 문자 문제가 있었어요.
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?' );
}
정직하지만,이 있는지 여부에 대한 방법 평가를 진실하다(그리고 다른 사람으로는 다음과 같이 여러 개 있는 방법)에 대답'd 있고,말하는 사람으로 실시한 수백 개의 인터뷰가 뭔가 될 것인:
"만,어쩌면 아래에서 예상한 상황에서는't 즉시 분명하다 그러나는 경우가 발생하이에서 실제 코드는 다음 사용하는 것이 일반적인 디버깅 기술을 어떻게 그리고 왜 더욱 쉽게 확인할 수 있게 되었습니다 무엇을 더욱 쉽게 확인할 수 있게 되었습니다 그리고 즉시 코드를 리팩터링을 피하는 상황이다...그러나 더 중요한 것:내가 절대적으로 절대 쓰는 코드에서는 첫 번째 장소이기 때문에 매우 정의는 복잡한 코드,그리고 내가 노력하기를 쓰지 않는 복잡한 코드를".
나는 몇 가지 인터뷰는 것을 범죄하는 것은 의미가 분명 매우 까다로운 질문이라는,그러나 나는't 마음이 있는 개발자는 의견을 때,특히 그들은 그 권고 생각할 수 있습 dovetail 나의 질문으로 의미 있는 문의에 대해 자체.
만약 당신이 이러한 면접 질문(또는 몇 가지 동일하게 예기치 않은 동작하는 코드)에 대해 생각 어떤 종류의 것을 발생시킬 수 있는 행동을 보이는 불가능한에서 먼저 눈:
Encoding이 경우는 변수에서 찾고 있는지 생각합니다. 이 경우 발생할 수 있습니다 당신이 의도적으로 혼란을 주위 유니코드를 사용하여[homoglyphs](https://en.wikipedia.org/wiki/Homoglyph#Unicode_homoglyphs 다)또는[공백 문자](https://stackoverflow.com/a/48274520/40347 용)변수의 이름처럼 또 다른 하나지만,인코딩이 문제가 될 수도 있습을 소개 실수로,예를 들어 복사할 때&붙여넣기 코드에서 웹을 포함하는 예상치 못한 유니코드 포인트(예를 들어 콘텐츠 관리 시스템을 어떤"auto-포맷"와 같은 교체fl
유니코드'LATIN 작은 합자 FL'(U+FB02)).
레이스:A경주-상태가 발생할 수 있습,즉 상황에 코드를 실행하지 않아 순서에 의해 예상합니다. 경쟁 조건을 자주에서 일어나는 멀티스레드 코드,하지만 여러 스레드가 아닌 요구 사항에 대한 경쟁 조건을 가능–asynchronicity 가 충분한(그리고 don't 혼란스러워비동기를 의미하지 않는 여러 쓰레드가 사용 후드).
참고 따라서 자바스크립트에서 무료로하지 않 경쟁 조건 때문에 그것은 하나의 스레드. 시기](https://medium.com/@slavik57/async-race-conditions-in-javascript-526f6ed80665)에 대한 간단한 하나의 스레드–그러나 비동기 예입니다. 의 컨텍스트에서 단 하나 문장의 경쟁 상태는 오히려 하에서 JavaScript.
JavaScript 웹 작업자와 조금 다르다,당신이 할 수 있는 여러 쓰레드. @mehulmpt 는 다음과 같은 우리에게 큰증명의 개념을 사용하여 웹자.
이러한 종류의 문제에 나타날 수 있습니다 많은 프로그래밍 언어,뿐만 아니라 자바스크립트,그래서 우리는't 을 보고 하나의 클래식[JavaScript WTFs](https://github.com/denysdovhan/wtfjs 다)여기1.
물론,인터뷰 질의 및 샘플 여기 모두 매우 고안된다. 하지만 그들은 좋은 것을 알림:
-부작용을 얻을 수 있습니다 정말 불쾌하고는 잘 설계된 프로그램에서 무료로 쓸모 없는 부작용이 나타납니다. -멀티-스레딩 및 변경 가능한 상태에 문제가 될 수 있습니다. -를 하지 않는 문자 인코딩을 가정하고 바로 이어질 수 있는 불쾌한다.
1예를 들어,당신은 예를 찾을 수 있습에서 완전히 다른 프로그래밍 언어(C#)을 전시한 부작용(는 명백한 것)여기.</하위>
를 사용하여프록시:
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
때==
강제 유형과 비교하기 위해 각각의 번호입니다. 이런 일:
{i:0}
에는i
시리 카운터a
a==
비교,a
's 형식으로 변환된 기본값a[징이다.toPrimitive]()
내부적으로기호입니다.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
으로 대부분의 다른 답변,이와 동등성 검사(==
),기 때문에 엄격한 평등사(===
)하지 않는 입력 강제 프록시을 가로챌 수 있습니다.