질문 : 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 표준 에서 가져온 것입니다.
[] + []
더하기 연산자를 사용하면 왼쪽 및 오른쪽 피연산자가 먼저 기본 형식으로 변환됩니다 ( §11.6.1 ). §9.1 에 따라 객체 (이 경우 배열)를 기본toString()
object.toString()
( §8.12.8 )을 호출 한 결과입니다. 배열의 경우 이는array.join()
( §15.4.4.2 ) 호출과 동일합니다. 빈 배열을 결합하면 빈 문자열이 생성되므로 더하기 연산자의 # 7 단계는 빈 문자열 인 두 개의 빈 문자열 연결을 반환합니다.[] + {}
[] + []
와 유사하게 두 피연산자가 먼저 기본 형식으로 변환됩니다. "Object objects"(§15.2)의 경우 이는 null이 아닌 정의되지 않은 개체의 경우"[object Object]"
( §15.2.4.2 ) 인object.toString()
{} + []
여기서{}
는 객체로 구문 분석되지 않고 대신 빈 블록으로 구문 분석됩니다 ( §12.1 , 최소한 해당 명령문을 표현식으로 강제하지 않는 한 나중에 더 자세히 설명합니다). 빈 블록의 반환 값은 비어 있으므로 해당 문의 결과는+[]
와 동일합니다. 단항+
연산자 ( §11.4.6 )는ToNumber(ToPrimitive(operand))
반환합니다. 이미 알고 있듯이ToPrimitive([])
는 빈 문자열이고 §9.3.1ToNumber("")
는 0입니다.{} + {}
앞의 경우와 유사하게 첫 번째{}
는 빈 반환 값이있는 블록으로 구문 분석됩니다. 다시 말하지만+{}
는ToNumber(ToPrimitive({}))
와ToPrimitive({})
는"[object Object]"
([] + {}
).+{}
의 결과를 얻으려면 문자열"[object Object]"
ToNumber
를 적용해야합니다. §9.3.1 의 단계를 따를 때 결과적으로NaN
을 얻습니다.문법이 String을 StringNumericLiteral 의 확장으로 해석 할 수없는 경우 ToNumber 의 결과는 NaN 입니다.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
을 호출해야합니다.m 이 NaN 이면 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
을 호출해야합니다.
m 이 NaN 이면 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
'프로그래밍 언어 > HTML,CSS,JS' 카테고리의 다른 글
Javascript에서 문자열의 첫 번째 문자 삭제 (0) | 2021.07.22 |
---|---|
각각 offsetWidth, clientWidth, scrollWidth 및 -Height 이해 (0) | 2021.07.22 |
AngularJS를 사용하여 체크박스 값 목록에 바인딩 하는 방법 (0) | 2021.07.22 |
VanillaJS가 무엇인지에 대해서 (0) | 2021.07.22 |
IMG와 CSS 배경 이미지의 적절한 사용시기 (0) | 2021.07.22 |