{}[true]
이다 [true]
하고 ![true]
있어야한다 false
.
그렇다면 왜 !{}[true]
평가 true
합니까?
답변
일반이 때문에 나는 그의를 생각 {}[true]
포함한 배열 다음에 빈 문 블록 (안 객체 리터럴)로 구문 분석 true
이다 true
.
한편, 도포 !
조작은 파서가 해석하게 {}
이하가되도록, 오브젝트 리터럴로 {}[true]
복귀하는 멤버 액세스하게 undefined
하고 !{}[true]
참 true
(대로 !undefined
이다 true
).
답변
때문에는 {}[true]
반환하지 않습니다 true
, 그러나 undefined
, 그리고 undefined
으로 평가된다 false
:
'use strict';
var b = {}[true];
alert(b); // undefined
b = !{}[true];
alert(b); // true
답변
때문에
{}[true]
로 평가 undefined
되며 !undefined
입니다 true
.
@schlingel에서 :
true
키 및 {}
해시 맵으로 사용됩니다. 키가있는 속성이 true
없으므로를 반환합니다 undefined
. 아니 undefined
되고 true
, 같은 예상.
콘솔 세션 ( Node.js [0.10.17]
) :
> {}[true]
undefined
> !{}[true]
true
> [true]
[ true ]
> ![true]
false
>
그러나 Chrome 콘솔에서 :
> !{}[true]
true
따라서 불일치가 없습니다. 이전 버전의 JavaScript VM을 사용하고있을 것입니다. 추가 증거가 필요한 사람들을 위해 :
최신 정보
함께 파이어 폭스 , 그것은 또한 평가 true
:
답변
혼란의 이유는 첫 번째 주장을 오해하기 때문입니다.
{}[true]
이다 [true]
실행할 때보고있는 것은 모호한 결과입니다. Javascript는 이와 같은 모호성을 처리하는 방법에 대해 정의 된 규칙 세트를 가지고 있으며,이 경우, 단일 명령문으로 표시되는 내용을 두 개의 개별 명령문으로 나눕니다.
따라서 Javascript는 위의 코드를 두 개의 별도 명령문으로 간주합니다. 첫째, {}
가 있고 완전히 별개 [true]
입니다. 두 번째 진술은 결과를 제공하는 것 [true]
입니다. 첫 번째 진술 {}
은 실질적으로 완전히 무시됩니다.
다음을 시도하여이를 증명할 수 있습니다.
({}[true])
즉, 인터프리터가 단일 명령문으로 읽도록 강제로 전체를 괄호로 묶습니다.
이제 문장의 실제 가치는 undefined
입니다. (이것은 나중에 다음 부분을 이해하는 데 도움이 될 것입니다)
이제 우리는 귀하의 질문의 첫 부분이 빨간 청어라는 것을 알고 있으므로 질문의 마지막 부분으로 넘어 갑시다.
그렇다면 왜! {} [true]가 true로 평가됩니까?
여기에도 같은 문장이 있지만 !
그 앞에 추가됩니다.
이 경우 Javascript의 규칙은 전체 내용을 단일 문으로 평가하도록 지시합니다.
앞의 문장을 괄호로 묶었을 때 일어난 일을 다시 참조하십시오. 우리는 얻었다 undefined
. 이번에는 효과적으로 똑같은 일을하지만 그 일 !
을 앞두고 있습니다. 그래서 코드는 다음과 같이 간단하게 할 수 !undefined
있는, true
.
잘만되면 그것은 조금 설명합니다.
복잡한 짐승이지만 여기서 배우는 교훈은 콘솔에서 문장을 평가할 때 괄호를 사용하여 가짜 결과를 피하는 것입니다.
답변
{}[true]
입니다 undefined
. 이것을 작성하려면 다음을 작성하십시오.
a = {};
a[true] === undefined // true
또는 간단히 :
({})[true] === undefined // true
우리는 알고 !undefined
있다 true
.
try {
if (injectCommandLineAPI && inspectedWindow.console) {
inspectedWindow.console._commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null);
expression = "with ((window && window.console && window.console._commandLineAPI) || {}) {\n" + expression + "\n}";
}
var result = evalFunction.call(object, expression);
if (objectGroup === "console")
this._lastResult = result;
return result;
}
finally {
if (injectCommandLineAPI && inspectedWindow.console)
delete inspectedWindow.console._commandLineAPI;
}
따라서 기본적으로
call
표현식으로 객체를 수행합니다 . 표현은 다음과 같습니다.
with ((window && window.console && window.console._commandLineAPI) || {}) {
{}+{};// <-- This is your code
}
보시다시피, 랩핑 괄호없이 표현식이 직접 평가됩니다.
자세한 내용은 이 질문 에서 찾을 수 있습니다 .
답변
여기에 대한 답변이 좋습니다. 여기 의사 코드에 대한 분석이 있습니다.
{}['whatever']
= 빈 블록, NewArray ( ‘whatever’) = NewArray ( ‘whatever’){}[true]
= 빈 블록, NewArray (true) = NewArray (true)!{}['whatever']
= LogicalNOT (convertToBool (NewObject.whatever)) = LogicalNOT (convertToBool (undefined)) = LogicalNOT (false) = true({}['whatever'])
= 그룹화 (NewObject.whatever) = 그룹화 (정의되지 않음) = 정의되지 않음
답변
이것은 {}
의미에서의 리터럴 표현이 Object
아니라 빈 범위 (또는 빈 코드 블록) 이기 때문에 발생합니다 .
{ var a = 1 }[true] // [true] (do the same thing)
범위 내에서 코드를 평가 한 다음 배열을 보여줍니다.
그리고 당신의
!{}[true]
이 범위를 int로 변환하고 동일한 배열을 true로 반환하십시오. 이 코드에는 부울 검사가 없습니다.
그리고 결과를 확인하려고하면 다음과 같은 결과가 나타 {}[true]
납니다 false
.
{}[true] -> [true] -> ![true] -> false
더 이상 범위가 없으므로.
따라서 !
귀하의 질문에 다음과 같이하십시오 :
!function() {
//...
}