프로그래밍 언어/HTML,CSS,JS

CodeMash 2012의 'Wat'강연에서 언급 된 JavaScript 동작에 대한 설명

Rateye 2021. 7. 22. 10:36
728x90
반응형
질문 : CodeMash 2012의 'Wat'강연에서 언급 된 이러한 기괴한 JavaScript 동작에 대한 설명은 무엇입니까?

CodeMash 2012에 대한 'Wat'강연은 기본적으로 Ruby 및 JavaScript의 몇 가지 기이 한 단점을 지적합니다.

http://jsfiddle.net/fe479/9/ 에서 결과의 JSFiddle을 만들었습니다.

(루비를 모르기 때문에) 자바 스크립트와 관련된 동작은 다음과 같습니다.

JSFiddle에서 내 결과 중 일부가 비디오의 결과와 일치하지 않는다는 것을 발견했으며 그 이유를 모르겠습니다. 그러나 JavaScript가 각 경우에서 어떻게 작동하는지 알고 싶습니다.

Empty Array + Empty Array
[] + []
result:
<Empty String>

JavaScript에서 배열과 함께 사용할 때 + 연산자에 대해 매우 궁금합니다. 이것은 비디오의 결과와 일치합니다.

Empty Array + Object
[] + {}
result:
[Object]

이것은 비디오의 결과와 일치합니다. 여기서 무슨 일이 일어나고 있습니까? 이것은 왜 객체입니다. + 연산자는 무엇을합니까?

Object + Empty Array
{} + []
result:
[Object]

비디오와 일치하지 않습니다. 영상에서는 결과가 0 인 반면 [Object]가 나옵니다.

Object + Object
{} + {}
result:
[Object][Object]

이것은 비디오와도 일치하지 않으며 변수를 출력하면 어떻게 두 개의 객체가 생성됩니까? 내 JSFiddle이 잘못되었을 수 있습니다.

Array(16).join("wat" - 1)
result:
NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN

wat + 1을 수행하면 wat1wat1wat1wat1 ...

문자열에서 숫자를 빼려고하면 NaN이 발생하는 간단한 동작이라고 생각합니다.

반응형
답변

보고있는 결과에 대한 설명 목록은 다음과 같습니다. 내가 사용하는 참조는 ECMA-262 표준 에서 가져온 것입니다.

  1. [] + []더하기 연산자를 사용하면 왼쪽 및 오른쪽 피연산자가 먼저 기본 형식으로 변환됩니다 ( §11.6.1 ). §9.1 에 따라 객체 (이 경우 배열)를 기본 toString() object.toString() ( §8.12.8 )을 호출 한 결과입니다. 배열의 경우 이는 array.join() ( §15.4.4.2 ) 호출과 동일합니다. 빈 배열을 결합하면 빈 문자열이 생성되므로 더하기 연산자의 # 7 단계는 빈 문자열 인 두 개의 빈 문자열 연결을 반환합니다.
  2. [] + {}[] + [] 와 유사하게 두 피연산자가 먼저 기본 형식으로 변환됩니다. "Object objects"(§15.2)의 경우 이는 null이 아닌 정의되지 않은 개체의 경우 "[object Object]" ( §15.2.4.2 ) 인 object.toString()
  3. {} + []여기서 {} 는 객체로 구문 분석되지 않고 대신 빈 블록으로 구문 분석됩니다 ( §12.1 , 최소한 해당 명령문을 표현식으로 강제하지 않는 한 나중에 더 자세히 설명합니다). 빈 블록의 반환 값은 비어 있으므로 해당 문의 결과는 +[] 와 동일합니다. 단항 + 연산자 ( §11.4.6 )는 ToNumber(ToPrimitive(operand)) 반환합니다. 이미 알고 있듯이 ToPrimitive([]) 는 빈 문자열이고 §9.3.1 ToNumber("") 는 0입니다.
  4. {} + {}앞의 경우와 유사하게 첫 번째 {} 는 빈 반환 값이있는 블록으로 구문 분석됩니다. 다시 말하지만 +{}ToNumber(ToPrimitive({}))ToPrimitive({})"[object Object]" ( [] + {} ). +{} 의 결과를 얻으려면 문자열 "[object Object]" ToNumber 를 적용해야합니다. §9.3.1 의 단계를 따를 때 결과적으로 NaN 을 얻습니다.문법이 String을 StringNumericLiteral 의 확장으로 해석 할 수없는 경우 ToNumber 의 결과는 NaN 입니다.
  5. Array(16).join("wat" - 1)§15.4.1.1§15.4.2.2에 따라 Array(16) 는 길이가 16 인 새 배열을 만듭니다. 조인 할 인수 값을 얻으려면 §11.6.2 단계 # 5 및 # 6에서 변환해야 함을 보여줍니다. ToNumber 사용하여 두 피연산자를 숫자로 변환합니다. ToNumber(1) 은 단순히 1 ( §9.3 )이고 ToNumber("wat") 다시 §9.3.1에 따라 NaN 입니다. §11.6.2의 7 단계에 따라 §11.6.3은피연산자 중 하나가 NaN 이면 결과는 NaN 입니다.Array(16).join 의 인수는 NaN 입니다. §15.4.4.5 ( Array.prototype.join "NaN" ( §9.8.1 ) 인수에 대해 ToString 을 호출해야합니다.mNaN 이면 String "NaN" 반환합니다.§15.4.4.5의 10 단계에 이어 "NaN" 과 빈 문자열의 연결을 15 번 반복하여 결과와 동일합니다. "wat" - 1 -1 대신 "wat" + 1 사용할 때 더하기 연산자는 "wat" 를 숫자로 변환하는 대신 1 Array(16).join("wat1") 호출합니다. .

 

§15.4.1.1§15.4.2.2에 따라 Array(16) 는 길이가 16 인 새 배열을 만듭니다. 조인 할 인수 값을 얻으려면 §11.6.2 단계 # 5 및 # 6에서 변환해야 함을 보여줍니다. ToNumber 사용하여 두 피연산자를 숫자로 변환합니다. ToNumber(1) 은 단순히 1 ( §9.3 )이고 ToNumber("wat") 다시 §9.3.1에 따라 NaN 입니다. §11.6.2의 7 단계에 따라 §11.6.3은

피연산자 중 하나가 NaN 이면 결과는 NaN 입니다.

Array(16).join 의 인수는 NaN 입니다. §15.4.4.5 ( Array.prototype.join "NaN" ( §9.8.1 ) 인수에 대해 ToString 을 호출해야합니다.

mNaN 이면 String "NaN" 반환합니다.

§15.4.4.5의 10 단계에 이어 "NaN" 과 빈 문자열의 연결을 15 번 반복하여 결과와 동일합니다. "wat" - 1 -1 대신 "wat" + 1 사용할 때 더하기 연산자는 "wat" 를 숫자로 변환하는 대신 1 Array(16).join("wat1") 호출합니다. .

{} + [] 케이스에 대해 다른 결과가 나타나는 이유에 대해 : 함수 인수로 사용할 때 문을 ExpressionStatement {} 를 빈 블록으로 구문 분석 할 수 없습니다. 대신 빈 개체 리터럴로 구문 분석됩니다.

출처 : https://stackoverflow.com/questions/9032856/what-is-the-explanation-for-these-bizarre-javascript-behaviours-mentioned-in-the

 

728x90
반응형