Chrome 콘솔에서 {} + {}가 더 이상 NaN이 아닌 이유는 무엇인가요?


144

오늘 콘솔에 NaN입력 할 때 Chrome 49가 더 이상 출력되지 않는 것으로 나타났습니다 {}+{}. 대신 문자열을 출력합니다 [object Object][object Object].

왜 이런거야? 언어가 바뀌 었습니까?


13
크롬은 이제이 작업을 더하기보다는 문자열 연결로 취급합니다. 왜, 나는 모르겠다, 이것이 왜 대답이 아닌 설명이다 :) 시도 var e = {}; e.toString()하고 당신은 내가 무슨 뜻인지 알 것이다
user428517

19
"언어가 바뀌 었습니까?" No.
Felix Kling

6
@FelixKling 것이다 언어의 변화는? ...아니. : c
cat

18
어쩌면 WATMAN 과 관련이 있습니까?
rickster

1
@rickster 그것이 내가 찾은 방법입니다. 프리젠 테이션을 위해 다시 작성했습니다.
Filip Haglund

답변:


152

Chrome devtools는 이제 암시 적으로 괄호 쌍으로 시작 {하고 끝나는 모든 것을 자동으로 래핑 하고 }( code 참조 ), 평가를 표현식으로 강제합니다. 그런 식으로 {}빈 객체를 만듭니다. 이력 ( ) 으로 돌아 가면 이전 줄이에 포함됩니다 (…).

왜? 잘 모르겠지만, 블록 대 객체 리터럴을 모르는 초보자에게는 혼란을 줄일 수 있다고 생각할 수 있습니다. 표현식을 평가하고 싶다면 더 도움이됩니다.

그리고 실제로 버그 499864 에서 논의 된 바와 같이 추론 입니다. 순수한 편의성. 그리고 노드 REPL도 그것을 가지고 있기 때문에 ( code 참조 ).


182
바보 크롬, {a:1}),({b:2}개체를 생성하지 오류를 던져야합니다.
Oriol


4
나는 왜 그런지 모르겠지만, 어떻게 든 메시지를 볼 때 "유명한"느낌이 들지만 그 페이지는이 페이지와 마찬가지로 공개적이지만 : D Weird StackOverflow problem. 다음은 문제에 대한 나의 오래된 답변입니다 stackoverflow.com/questions/17268468/…
Benjamin Gruenbaum

3
현재 구현이 마음에 들지 않으며 고칠 계획입니다. bugs.chromium.org/p/chromium/issues/detail?id=499864#c17
Zirak

1
@Zirak 행운을 빕니다. 그러나 개선하고 싶다면 )주석 앞에있는 경우 삽입하기 전에 줄 바꿈을 추가하는 것이 {a:3} // :-}좋습니다. 예를 들어 여전히 객체를 생성 할 수 있습니다.
Oriol

44

이 확인 후 위쪽 화살표를 공격하는 경우, 당신은 대신 것을 알 수 있습니다 {} + {}그것을 표시 ({} + {}), 결과를 "[object Object][object Object]".

이에 비해 Firefox에서는 {} + {}여전히을 표시 NaN하지만 그렇게 ({} + {})하면을 표시합니다 "[object Object][object Object]".

따라서 Chrome 이이 작업을 볼 때 주변 괄호를 자동으로 추가하는 것처럼 보입니다.


22
이 대답은 맞습니다. 하지만 와우, 크롬이 그렇게 좋아하는지 잘 모르겠습니다. 나쁜 구글.
user428517

1
@ sgroves 나는 이것이 카나리아에서 동일하고 그것이 의도적으로 이루어 졌는지 또는 실제로 버그인지 알고 싶습니다.
J. Titus

8
{} + {}"위생되지 않은" 은 빈 블록으로 해석 되기 때문에 ({} + {})처리됩니다 . + {}{}
Gregory Nisbet

7
처음에 NaN이 반환되는 이유는 무엇입니까?
0x499602D2

25
0x499602D2 @ : 당신은 괄호을 (또는 다른 파서 원인이 아니라 문보다 표현을 기대로 변화에)하지 않는 한, 초기 때문에 {}단지 빈 코드 블록이며, 우리를 떠나, 무시 +{}단항 인 +및 빈 개체 이니셜 라이저. +인수를 숫자로 강제 변환합니다. 이는 객체를 프리미티브로 변환하는 것 ( toString이 경우 결국은 결과가 됨 "[object Object]") 을 포함하므로 유효한 숫자로 변환 할 수 없기 때문에 +"[object Object]"어느 것이 됩니다. NaN"[object Object]"
TJ Crowder

4

콘솔과 관련하여 Chrome 54 기준 :

📎- "블록을 개체로 변환했습니다"-Clippy 불행히도 Clippy 인용문을 직접 추가했습니다. 콘솔은 사용자를 위해 수행 한 작업에 대한 정보를 제공하지 않습니다.

새로운 규칙은 엄청나게 간단 하여이 어려운 두 문자를 힘들게 입력 o=하거나 0,오브젝트 리터럴을 콘솔에 붙여 넣기 전에 어려움을 덜어줍니다 .

  • 다음으로 시작하는 코드가있는 경우 : 선택적 공백, (주석이 허용되지 않음) 뒤에 {;
  • 그 코드는 객체로 해석 될 수 있습니다.
  • 다음과 같은 경우가 아니면 해당 객체 뒤에 다른 코드가 없습니다.
  • 첫 번째 객체 다음의 코드는 이진 연산자입니다.
  • 그룹화를 포함하여 원하는만큼 많은 작업을 수행 할 수 있습니다.
  • 최종 연산자가 오른쪽 위치에 Object 리터럴이있는 경우;
  • 그 최종 객체는 괄호 안에 그룹화되지 않았습니다
  • 그 코드는 세미콜론으로 끝나지 않습니다
  • 코드 뒤에 주석이 없습니다 (내부 주석은 초기 또는 최종 위치에 있지 않는 한 허용됩니다)
  • 그래야만 자바 스크립트 (실제로 유효한 코드 일 수도 있고 아닐 수도 있음)가 유효한 객체로 다시 표시됩니다. 코드가 해석되었다는 알림을받지 않습니다.

{wat:1}),({wat:2} 마지막으로 다시 오류입니다.

{let i=0;var increment=_=>i++} 마지막으로 올바르게 허용되며 이는 클로저를 수행하는 아주 좋은 방법입니다.

그러나 다음은 잘못 된 객체입니다. @ Bergi에서 언급 한 것처럼 편리합니다 .JS가 잘못 해석하여 도움을줍니다! 스펙은 아무것도 지정되지 않은 리터럴 1로 레이블이 지정된 명령문 "foo"가있는 블록입니다.

{foo:1}

위와 동일해야합니다

if(1) {
    foo: 1
}

다음은 앞에 주석이 있기 때문에 블록으로 올바르게 취급됩니다!

//magic comment
{foo:1}

이것도 마찬가지입니다 :

{foo:1}
//also magic

이것은 객체입니다.

{foo:
//not so magic comment
1}

이것은 오류입니다

//not so magic comment
{foo:1}.foo

이것도 마찬가지입니다 :

{foo:1}.foo

이건 괜찮아:

1..wat

undefined

이것도 마찬가지입니다 :

['foo'][0]

다음은 표현 위치로 엉망이 된 객체로 올바르게 해석됩니다 0,.

0,{foo:1}.foo

왜 그들이 그 가치를 괄호 안에 싸는 지 모르겠습니다. JS는 우스운 디자인 결정을 가지고 있지만이 상황에서 더 잘 행동하게 만드는 것은 실제로 옵션이 아니며 콘솔은 JS를 올바르게 실행해야하며 크롬은 우리가 생각한다고 생각하지 않을 것이라고 확신해야합니다 실제로 다른 일을하는 것을 의미했습니다.

쉼표 연산자가 마음에 들지 않으면 할당을 사용할 수 있습니다

x = {foo:1}.foo

그것이 서 있기 때문에

{} + {} + {}

"[object Object][object Object][object Object]"

;{} + {} + {}

"NaN[object Object]"

미쳤고 일관된 내가 처리 할 수있는 ...


REPL은 REPL 인 언어가 아닙니다. 무엇보다도 문자열을 언어로 전달 합니다. Chrome REPL이 수행하는 언어 자체가 아닌 몇 가지 사항이 있습니다 . 그들은 매우 유용하므로 평범한 언어를 고수하지 않아서 정말 기쁩니다.
gman

@gman A REPL 문자열을 읽고, 평가하고, 결과를 인쇄 한 후 다음 동적 코드를 읽을 준비를합니다. 링크 된 페이지에 잘못된 JavaScript가 없습니다. 콘솔 컨텍스트로 범위가 지정된 "$ _"변수는 REPL에서만 의미가있는 편의성입니다. 그럼에도 불구하고 "$ _"는 유효한 변수 이름이며, 나머지는 일반 JavaScript 및 일반 함수로 호출 된 클래스입니다.
제임스 웨이크 필드

당신의 요점이 무엇인지 모릅니다. 내 요점은 언어는 하나이고, 환경은 다른 것입니다. 당신은 당신의 대답에 예를 들었습니다. JS에서 {foo:1}{foo:1}//같은 일을 생성한다. Chrome JS REPL에서는 그렇지 않습니다. REPL은 단순히 JS를 평가하는 것 이상의 일을하고 있습니다. 문자열을 처리하고 다른 것으로 결정합니다.
gman

var x = eval('{a:1}')유효한 JavaScript에서 x는 이제 1이 아니라보다 직관적 인 객체 {a : 1}이 아닙니다. 그렇습니다. 이상하지만, 이상한 일을하기 때문에 언어를 바꿀 수는 없습니다. JSON 문자열 이외의 모든 것은 JavaScript로 해석되고 평가됩니다. 0,JSON을 붙여 넣기 전에 입력 하는 것은 어렵지 않습니다. 또는 편의상 문자열이 JavaScript 대신 객체로 해석되었다는 경고에 만족할 것입니다.
제임스 웨이크 필드
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.