의 자바스크립트 예제 분석 게리 베른하르트의”왓”토크

의 자바스크립트 예제 분석 이 글은 게리 베른하르트의 환상적인”왓”토크에 대한 경의를 표하며,그는 루비와 자바스크립트에서 일부 언어 구조의 특징을 지적한다. 당신이 이야기를 아직 보지 않은 경우,난 강력하게 당신이 시간이 걸릴 정확하게 할 것이 좋습니다! 그것은 단지 약 4 분 길고 매우 재미 있어요,약속.

그의 이야기에서,게리는 자바 스크립트 코드의 네 조각을 보여줍니다:

자바 스크립트의 특성

우리는 괄호,중괄호 및 더하기 기호를 많이 참조하십시오. 다음은 이러한 조각이 평가하는 것입니다:

  • + == ""
  • + {} == ""
  • {} + == 0
  • {} + {} == NaN

이 예를 처음 보았을 때,나는 생각했다:”와우,그것은 지저분 해 보인다!”결과는 일관성이 없거나 임의적 인 것처럼 보일 수 있지만 여기에 나와 함께하십시오. 이 보기의 모두는 실제적으로 아주 일관되고 처럼 보는 것처럼 나쁘다!

#단편#1: +

첫 번째 조각부터 시작하겠습니다:

 + // ""

보시다시피+연산자를 두 개의 빈 배열에 적용하면 빈 문자열이 생성됩니다. 배열의 문자열 표현은 쉼표와 함께 연결된 모든 요소의 문자열 표현이기 때문입니다:

.toString()// "1,2,3".toString()// "1,2".toString()// "1".toString()// ""

빈 배열에는 요소가 포함되어 있지 않으므로 문자열 표현은 빈 문자열입니다. 따라서 두 개의 빈 문자열의 연결은 또 다른 빈 문자열입니다.

#단편#2: + {}

지금까지,너무 좋아. 이제 두 번째 조각을 살펴 보겠습니다:

 + {}// ""

두 개의 숫자를 다루지 않기 때문에+연산자는 두 개의 숫자 값을 추가하는 대신 문자열 연결을 다시 수행합니다.

이전 섹션에서,우리는 이미 빈 배열의 문자열 표현이 빈 문자열 것을 보았다. 여기서 빈 개체 리터럴의 문자열 표현은 기본""값입니다. 빈 문자열 앞에 추가하면 값이 변경되지 않으므로""가 최종 결과입니다.

자바스크립트에서 객체는 메서드가 호출되는 객체의 사용자 지정 문자열 표현을 반환하는toString()이라는 특수 메서드를 구현할 수 있습니다. 우리의 빈 객체 리터럴은 그러한 메소드를 구현하지 않으므로Object프로토 타입의 기본 구현으로 되돌아갑니다.

#단편#3: {} +

나는 지금까지 그 결과가 너무 예상치 못한 것이 아니라고 주장 할 것이다. 그들은 단순히 자바 스크립트에서 유형 강제 변환 및 기본 문자열 표현의 규칙을 따르고 있습니다.

그러나{} + 은 개발자가 혼란스러워하는 곳입니다:

{} + // 0

위의 줄을 브라우저 콘솔과 같은 자바 스크립트 레플에 입력하면 왜0(숫자 0)이 표시됩니까? 결과는 + {}와 같은 문자열이 아니어야합니까?

수수께끼를 풀기 전에+연산자를 사용할 수있는 세 가지 방법을 고려하십시오.:

// 1) Addition of two numeric values2 + 2 == 4// 2) String concatenation of two values"2" + "2" == "22"// 3) Conversion of a value to a number+2 == 2+"2" == 2

처음 두 경우+연산자는 두 개의 피연산자(왼쪽 및 오른쪽)가 있기 때문에 이항 연산자입니다. 세 번째 경우+연산자는 오른쪽에 단일 피연산자만 있기 때문에 단항 연산자입니다.

또한 자바 스크립트에서{}의 두 가지 가능한 의미를 고려하십시오. 일반적으로{}는 빈 객체 리터럴을 의미하지만,문 위치에 있으면 자바 스크립트 문법은{}를 빈 블록을 의미하도록 지정합니다. 다음 코드는 개체 리터럴이 아닌 두 개의 빈 블록을 정의합니다:

{}// Empty block{ // Empty block}

의 다시 우리의 조각을 살펴 보자:

{} + 

자바 스크립트 엔진이 코드를 보는 방식을 명확하게 만들기 위해 공백을 조금 변경하겠습니다:

{ // Empty block}+;

이제 우리는 여기서 무슨 일이 일어나고 있는지 명확하게 볼 수 있습니다. 우리는 빈 배열에서 작동하는 단항+식을 포함하는 또 다른 문 뒤에 블록 문이 있습니다. 후행 세미콜론은 다음 규칙에 따라 자동으로 삽입됩니다(자동 세미콜론 삽입).

브라우저 콘솔에서+0로 평가되는지 쉽게 확인할 수 있습니다. 빈 배열에는 문자열 표현으로 빈 문자열이 있으며,이 문자열은+연산자에 의해 숫자 0 으로 변환됩니다. 마지막으로 마지막 문 값(이 경우+)이 브라우저 콘솔에 의해 보고됩니다.

또는 두 코드 조각을 에스프리마와 같은 자바스크립트 파서에 공급하고 결과 추상 구문 트리를 비교할 수 있습니다. 여기에 대한 표준입니다 + {}:

{ "type": "Program", "body": }, "right": { "type": "ObjectExpression", "properties": } } } ], "sourceType": "script"}

그리고 여기{} + :

{ "type": "Program", "body": }, { "type": "ExpressionStatement", "expression": { "type": "UnaryExpression", "operator": "+", "argument": { "type": "ArrayExpression", "elements": }, "prefix": true } } ], "sourceType": "script"}

혼란은 객체 리터럴과 블록 모두에 중괄호를 사용하는 자바 스크립트 문법의 뉘앙스에서 비롯됩니다. 문 위치에서 여는 중괄호는 블록을 시작하고 식 위치에서 여는 중괄호는 개체 리터럴을 시작합니다.

#단편#4: {} + {}

마지막으로,우리의 마지막 조각을 빠르게 살펴 보겠습니다{} + {}:

{} + {}// NaN

음,두 개의 객체 리터럴을 추가하는 것은 문자 그대로”숫자가 아닙니다”-하지만 여기에 두 개의 객체 리터럴을 추가하는 것입니까? 중괄호가 다시 당신을 속일 수 있도록하지 마십시오! 이 무슨 일이 일어나고 있는지입니다:

{ // Empty block}+{};

이전 예제와 거의 같은 거래입니다. 그러나 이제 단항 더하기 연산자를 빈 객체 리터럴에 적용하고 있습니다. 이는 기본적으로Number({})를 수행하는 것과 동일하며,객체 리터럴을 숫자로 변환 할 수 없기 때문에NaN이 발생합니다.

자바스크립트 엔진이 두 개의 빈 객체 리터럴로 코드를 구문 분석하려면 첫 번째 리터럴(또는 전체 코드 조각)을 괄호 안에 래핑합니다. 이제 예상 결과를 볼 수 있습니다:

({}) + {}// ""({} + {})// ""

여는 괄호를 사용하면 구문 분석기가 식을 인식하려고 시도하므로{}를 블록(문)으로 취급하지 않습니다.

#요약

이제 네 개의 코드 조각이 이러한 방식을 평가하는 이유를 확인해야 합니다. 그것은 임의적이거나 무작위적인 것이 아닙니다;형식 강요의 규칙은 사양과 언어 문법에 규정된 대로 정확하게 적용됩니다.

여는 중괄호가 문에 나타나는 첫 번째 문자인 경우 개체 리터럴이 아닌 블록의 시작으로 해석됩니다.

답글 남기기

이메일 주소는 공개되지 않습니다.