분류 javascript

내가 본 최고의 JavaScript Meme, 자세히 설명

컨텐츠 정보

  • 조회 392 (작성일 )

본문

실수로 Reddit 에서 이 JavaScript meme을 발견했으며 이것이 내가 본 것 중 최고입니다.


https://www.freecodecamp.org/news/explaining-the-best-javascript-meme-i-have-ever-seen/ 


best-js-meme-to-date-2 


개발자 도구에서 각 코드 스니펫을 실행하여 이 meme의 정확성을 확인할 수 있습니다. 결과는 놀랍지 않지만 여전히 실망스럽습니다.


왜 이런 일이 발생합니까? 


경험을 통해, 나는 가시가 많은 소나무를 지키면서 JavaScript의 매끄러운 면을 포용하는 법을 배웠습니다. 그럼에도 불구하고,이 코너 케이스의 세부 사항은 여전히 ​​저를 닉하게 했습니다.


카일 심슨의 말처럼 ...


"아무도 JS를 아는 사람은 전혀 없다고 생각합니다." 


이러한 경우가 발생하면 JavaScript를 기반으로 하는 공식 ECMAScript 사양을 참조하는 것이 가장 좋습니다.


스펙을 가지고 여기에서 무슨 일이 일어나고 있는지 깊이 이해합시다.


패널 1-강압 소개 

panel-1-1 


개발자 콘솔에서 0 == "0"을 실행하면 왜 true를 반환합니까?


0은 숫자이고 "0"은 문자열이므로 절대로 같아서는 안됩니다! 대부분의 프로그래밍 언어는 이를 존중합니다. 예를 들어 Java에서 0 == "0"은 다음을 반환합니다.

error: incomparable types: int and String

이것은 완벽하게 이해됩니다. Java에서 int와 String을 비교하려면 먼저 동일한 유형으로 변환해야 합니다.


그러나 이것은 JavaScript입니다.


==를 통해 두 값을 비교할 때 값 중 하나에 강제가 적용될 수 있습니다.


강제 (Coercion) – 한 유형에서 다른 유형으로 값을 자동으로(Automatically) 변경합니다.


여기서 핵심 단어는 자동입니다. 자바 스크립트는 타입을 명시적으로 변환하는 대신 배후에서 지원합니다.


이것은 의도적으로 악용하는 경우 편리하지만 그 의미를 알지 못하면 잠재적으로 해로울 수 있습니다.


여기에 공식 ECMAScript 언어 사양이 있습니다. 관련 부분을 설명하겠습니다.


x가 숫자이고 y가 문자열이면 x == ToNumber (y)를 반환합니다. 


따라서 우리의 경우 0 == "0":


0은 숫자이고 "0"은 문자열이므로 0 == ToNumber ( "0")를 반환합니다. 


우리의 문자열 "0"은 비밀리에 0으로 변환되었으며 이제 일치합니다!

0 == "0" // true
// The second 0 became a number!
// so 0 equals 0 is true....

패널 2- 배열이 너무 강해지다 

panel-2 


이 넌센스는 문자열, 숫자 또는 부울과 같은 프리미티브로 제한되지 않습니다. 다음 비교는 다음과 같습니다.

0 == [] // true
// What happened...?

다시 강요! 스펙의 관련 부분을 설명해 드리겠습니다.


x가 문자열 또는 숫자이고 y가 Object이면 x == ToPrimitive (y)를 반환합니다. 


여기에 세 가지 :


1. 예, 배열은 객체입니다 


2. 빈 배열은 빈 문자열이 됩니다 


스펙에 따르면 JS는 먼저 객체의 toString 메소드를 찾아서 이를 강제합니다.


배열의 경우 toString은 모든 요소를 ​​결합하여 문자열로 반환합니다.

[1, 2, 3].toString() // "1,2,3"
['hello', 'world'].toString() // "hello,world"

배열이 비어 있으므로 참여할 것이 없습니다! 따라서...

[].toString() // ""

스펙의 ToPrimitive는 이 빈 배열을 빈 문자열로 바꿉니다. 편의 (또는 혼동)에 대한 참조는 여기여기에 있습니다.


3. 빈 문자열은 0이 됩니다 


배열을 ""로 강제 변환 했으므로 이제 첫 번째 알고리즘으로 돌아갑니다 ...


x가 숫자이고 y가 문자열이면 x == ToNumber (y)를 반환합니다. 


따라서 0 == ""


0은 숫자이고 ""는 문자열이므로 0 == ToNumber ( "")를 반환합니다. 


따라서 0 == 0을 다시 한 번 ...


패널 3-빠른 요약 

panel-3-1 


이것은 true입니다

0 == "0" // true

강제는 이것을 0 == ToNumber ( "0")로 바꿉니다.


이것은 true입니다

0 == [] // true

강제는 두 번 실행되기 때문에 :

  1. ToPrimitive ([])는 빈 문자열을 제공합니다
  2. 그런 다음 ToNumber ( "")는 0을 제공합니다.

그렇다면 위의 규칙에 따라 무엇을 반환해야 합니까?

"0" == []

패널 4-거짓! 

panel-4-1 


규칙을 이해하면 이 부분이 의미가 있습니다.


비교는 다음과 같습니다.

"0" == [] // false

스펙을 다시 한 번 참조하십시오.


x가 문자열 또는 숫자이고 y가 Object이면 x == ToPrimitive (y)를 반환합니다. 


그 의미는...


"0"은 문자열이고 []는 Object이므로 x == ToPrimitive ([])를 반환합니다. 


ToPrimitive ([])는 빈 문자열을 반환합니다. 비교는 이제

"0" == ""

"0"과 ""는 모두 문자열이므로 JavaScript는 더 이상의 강제가 필요하지 않습니다. 이것이 우리가 틀리는 이유입니다.


결론 


트리플 이퀄라이저를 사용하고 밤에는 푹 자십시오.

0 === "0" // false
0 === [] // false
"0" === [] // false

그것은 강압을 완전히 피하므로 더 효율적이라고 생각합니다!


그러나 성능 향상은 거의 의미가 없습니다. 실제 승리는 코드에 대한 자신감이 높아져서 키스트로크가 그만한 가치가 있다는 것입니다.