ES6 즉시 화살표 기능을 호출


149

Node.js콘솔 (4.1.1 및 5.3.0에서 테스트)에서 작동하지만 브라우저 (Chrome에서 테스트)에서 작동하지 않습니까? 이 코드 블록은 기록하는 익명 함수를 작성하고 호출해야합니다 Ok.

() => {
  console.log('Ok');
}()

또한 위의 노드에서 작동 하지만 작동 하지 않습니다.

n => {
  console.log('Ok');
}()

이것도 아닙니다 :

(n) => {
  console.log('Ok');
}()

이상한 점은 매개 변수가 추가되면 실제로 SyntaxError호출하는 부분에 실제로 a 를 던진다는 것 입니다.


8
좋은 질문. 두 파라미터 버전은 바벨 작업
CodingIntrigue

2
관심이 (n => { console.log("Ok"); })();없으십니까?
CodingIntrigue

(n => { console.log("Ok"); })(), Chrome 개발자 콘솔에서도 작동
XCS

3 년 후 답은? 반드시 아래 3 가지 답변 중 하나를 받아 들여야합니까?!
joedotnot

@ joedotnot 명확한 대답을 얻지 못했습니다. 주로 Node.js의 이상한 구현이었습니다. 최신 버전의 Node.js첫 번째 버전에서는 더 이상 작동하지 않는 것 같습니다.
XCS

답변:


194

이름을 필요로하지 않고 유효한 JavaScript로 만드는 함수 정의 대신 함수 표현식 으로 만들어야합니다 .

(() => {
  console.log('Ok');
})()

IIFE 와 동일

(function(){
   console.log('Ok')
})();

그리고 이것이 Node.js에서 작동하지만 크롬에서는 작동하지 않는 가능한 이유는 파서가이를 자체 실행 함수로 해석하기 때문입니다.

function() { console.log('hello'); }();

Node.js이것은 잘 작동합니다. 이것은 함수 표현식이며 크롬과 파이어 폭스이며 대부분의 브라우저는이 방식으로 해석합니다. 수동으로 호출해야합니다.

파서가 함수 표현식을 기대하도록 지시하는 가장 널리 사용되는 방법은 JavaScript에서 parens에 명령문을 포함 할 수 없기 때문에 함수 표현식을 parens로 감싸는 것입니다. 이때 파서가 함수 키워드를 만나면 함수 선언이 아니라 함수 표현식으로 구문 분석하는 것을 알게됩니다.

매개 변수가 지정된 버전 과 관련하여 작동합니다.

((n) => {
  console.log('Ok');
})()

4
첫 번째 예제는 작동 Node.js하고 실제로 값을 기록합니다. 내 질문은 왜 작동합니까? 그리고 매개 변수를 추가 할 때 왜 그렇지 않습니까?
XCS

1
나는에 익숙하고 IIFE코드를 수정하는 방법을 알고 있습니다. 예를 들어, 매개 변수없이 작동했지만 매개 변수를 추가 IIFE할 때 왜 작동하지 않는지 궁금 n합니다.
XCS

3
나는 downvote하지 않았다, 그러나 노드에서 매개 변수화 된 버전이 아닌 작업을 수행하는 이유 질문은 때 매개 변수없이 동일한 정의는 않습니다 - 그것은 익명 함수의 노드 / 크롬 구현의 차이를 묻는 아니에요
CodingIntrigue

1
알기 쉽지만 이전에 언급 한 것처럼 질문에 대답하지 않습니다.- 매개 변수없이 정확히 동일한 정의가 수행 될 때 매개 변수화 된 버전이 노드에서 작동하지 않는 이유
jkris

그러나 function(){}()화살표 기능 과 동등한 기능은 무엇입니까? 함수 객체에 노출 된 함수 표현식을 원하면 그로부터 보호하십시오.
dabadaba

18

이들 중 어느 것도 괄호없이 작동해서는 안됩니다.

왜?

사양에 따르면 :

  1. ArrowFunctionAssignmentExpression 아래나열됩니다.
  2. (A)의 LHS CallExpression는 해야 MemberExpression , SuperCall 또는 CallExpression

그래서 ArrowFunction은 a의 LHS에있을 수 없습니다 CallExpression .


이것이 효과적으로하는 방법을 의미 =>, 해석되어야하는 것은 대입 연산자와 같은 수준의 동일한 종류에 작동하다 =, +=

의미

  • x => {foo}() 하지 않습니다(x => {foo})()
  • 통역사는 다음과 같이 해석하려고 시도합니다. x => ({foo}())
  • 따라서 여전히 SyntaxError입니다.
  • 따라서 인터프리터는 (반드시 잘못된 것이라 판단하고 SyntaxError를 던집니다.

여기 Babel에도 버그가있었습니다 .


이것들은 몇 가지 유효한 포인트이지만 작동하는 첫 번째 버전을 다음과 같이 () => ({console.log('Ok')}())바꾸면 더 이상 작동하지 않습니다. 따라서 실제로 그렇게 해석하지는 않습니다.
XCS

@Cristy 유효한 Arrow Function 프로덕션이 아닙니다. Object 리터럴 (괄호로 묶음)로 Object를 작성하려고 console.log(...)하는데 유효한 키 이름이 아니라고 생각합니다.
thefourtheye

@Cristy : 예, 위의 해석 부분 ( "평균"비트)이 정확하지 않을 수 있지만 사양 부분은 내가 알 수있는 한 멀리 있습니다. : 그것은 또한 내가 V8에서 얻을 오류에 맞는 SyntaxError: Unexpected token (합니다 (가리키는 (()끝이 아닌 (의를 console.log(...)).
TJ Crowder

@ TJCrowder 당신이 옳습니다. 오류 메시지를 변경하고 말하려는 내용이 전달되지 않기 때문에 그 사실을 깨달을 것입니다 (즉 (, 통역사가 유효한 해석을 찾으려고 노력하면서 포기하고 포기했습니다) "이것은 틀렸어 야한다"), 어쨌든 나는 통역사가 실제로 어떻게 작성되는지 모르기 때문에 틀릴 수있다
Paul S.

이 위치에서 유효한 토큰이 아닌지 궁금합니다. 세미 콜론을 삽입하지 않습니까?
thefourtheye

2

이와 같은 문제가 발생하는 이유는 콘솔 자체가 현재 대상으로하는 컨텍스트의 전체 범위를 모방하려고하기 때문입니다. 또한 콘솔에 작성한 명령문 및 표현식에서 리턴 값을 캡처하여 결과로 표시되도록 시도합니다. 예를 들어,

> 3 + 2
< 5

여기서는 표현식 인 것처럼 실행되지만 명령문 인 것처럼 작성했습니다. 일반 스크립트에서는 값이 삭제되지만 여기서는 전체 명령문을 함수 컨텍스트 및 명령문으로 랩핑하는 것과 같이 코드가 내부적으로 엉망이 return되어 발생하는 문제를 포함하여 모든 종류의 이상한 효과가 발생합니다.

이는 스크립트의 일부 ES6 코드가 제대로 작동하지만 Chrome 개발자 도구 콘솔에서는 작동하지 않는 이유 중 하나입니다.

노드 및 Chrome 콘솔에서 이것을 실행하십시오.

{ let a = 3 }

노드 또는 <script>태그에서는 정상적으로 작동하지만 콘솔에서는을 제공합니다 Uncaught SyntaxError: Unexpected identifier. 또한 VMxxx:1평가 된 소스를 검사하기 위해 클릭 할 수 있는 형식으로 소스에 대한 링크를 제공합니다 .

({ let a = 3 })

왜 이렇게 했습니까?

대답은 결과를 호출자에게 반환하고 콘솔에 표시 할 수 있도록 코드를 표현식으로 변환해야한다는 것입니다. 명령문을 괄호로 묶어 표현식을 작성할 수 있지만, 위의 블록은 구문 상 올바르지 않습니다 (표현식은 블록 선언을 가질 수 없음).

콘솔은 코드에 대해 똑똑하여 이러한 엣지 사례를 해결하려고 시도하지만이 답변의 범위를 벗어납니다. 버그를 수정하여 문제를 고칠 수 있는지 확인할 수 있습니다.

다음은 매우 유사한 좋은 예입니다.

https://stackoverflow.com/a/28431346/46588

코드를 작동시키는 가장 안전한 방법은 코드를 표현식으로 실행하고 SyntaxError소스 링크를 검사 하여 실제 실행 코드가 무엇인지 확인하고 그로부터 솔루션을 리버스 엔지니어링하는 것입니다. 일반적으로 전략적으로 배치 된 괄호 쌍을 의미합니다.

간단히 말해 콘솔은 가능한 한 정확하게 글로벌 실행 컨텍스트를 에뮬레이션하려고하지만 v8 엔진 및 JavaScript 시맨틱과의 상호 작용 제한으로 인해 해결하기가 어렵거나 불가능한 경우가 있습니다.


1
그것은 요점입니다. 매개 변수에 관심이 있지만 매개 변수 세트에서는 작동하지 않습니다.
XCS

네 요점이 보여요 차이점은 Chrome 개발자 도구 콘솔이 실제로 코드를 실행하는 방식에 있습니다. 이를 반영하여 답변을 편집하겠습니다.
Klemen Slavič

0

나는 이런 질문을했다 :

@getify이 질문을했습니다 : #IIFE 패턴을 생성하기 위해 함수 선언 주위에 paran을 사용하여 함수 표현식으로 변환 한 다음 호출합니다. 이제 화살표 기능 IIFE에서 왜 우리는 paran이 필요합니까?! 화살표 함수는 기본적으로 이미 표현식이 아닙니까?!

그리고 이것은 Kyle Simpson의 답변입니다.

화살표 함수 expr이지만 "연산자 우선 순위"(sorta)의 주변 parens b / c가 필요하므로 arrow-IIFE를 호출하는 마지막 parens는 본문의 마지막 토큰이 아니라 전체 함수에 적용됩니다. .

x => console.log(x)(4)

vs

(x => console.log(x))(4)

2020 년 6 월 12 일 getify (@getify)


내 질문은 왜 다른 컴파일러가 아닌 일부 컴파일러에서 작동했는지였습니다.
XCS


당신은 옳습니다, 다르게 행동하지만 JavaScript 사양은 모두 동일합니다. 나는 어느 것이 옳았는지, JS 사양 이이 사건에 대해 무엇을 말하고 있으며, 인수없이 작동하지만 인수로 작동하지 않는 방법에 대해 궁금합니다. 더 기술적 인 답변을 찾고있었습니다.
XCS

귀하의 예는 매우 분명합니다. 첫 번째 경우 실제로 호출해야합니다 console.log(x)(4).
XCS

나는 여기서 추측하고 있지만 다음과 같이 설명하는 것이 매우 합리적이라고 생각합니다. 화살표 함수 표현식에서 매개 변수를 사용하지 않을 때 우리는 반드시 파 렌스를 사용해야하며 이는 엔진이 화살표임을 분명히합니다. 함수 표현식,하지만 우리는 하나의 매개 변수가 때 괄호없이 아주 명확 될 수있는 임의이다가이 함수와 그 엔진, 우리는 전체 함수 표현식 주위에 괄호 한 쌍을 넣어 가지고 혼란을 해결하기 위해 혼란
Ershad을 Qaderi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.