화살표 함수(arrow function)는 ES2015에서 추가된 함수 표현을 간단하게 할 수 있게 해주는 문법으로, 평소에 자주 사용하고 있었지만 일반 함수와 구체적으로 어떤 점이 다른 지 모르고 있어서 이번 기회에 정리해 보고자 한다.
화살표 함수는 parameter => body
의 형태로, 함수의 파라미터와 바디 사이에 화살표를 표기하는 식으로 표현한다.
(a, b, c) => ...
a => ...
(a) => a + 1
(a) => { return a + 1 }
화살표 함수를 평가할 때 InstantiateArrowFunctionExpression연산을 통해 함수객체로 인스턴스화된다.
1. If name is not present, set name to "".
2. Let scope be the LexicalEnvironment of the running execution context.
3. Let privateScope be the running execution context's PrivateEnvironment.
4. Let sourceText be the source text matched by ArrowFunction.
5. Let closure be OrdinaryFunctionCreate(%Function.prototype%, sourceText, ArrowParameters, ConciseBody, lexical-this, scope, privateScope).
6. Perform SetFunctionName(closure, name).
7. Return closure.
5번의 OrdinaryFunctionCreate연산이 실질적으로 함수객체를 생성하는 역할을 한다.
OrdinaryFunctionCreate는 다음과 같은 과정을 수행한다
1. Let internalSlotsList be the internal slots listed in Table 34.
2. Let F be ! OrdinaryObjectCreate(functionPrototype, internalSlotsList).
3. Set F.[[Call]] to the definition specified in 10.2.1.
4. Set F.[[SourceText]] to sourceText.
5. Set F.[[FormalParameters]] to ParameterList.
6. Set F.[[ECMAScriptCode]] to Body.
7. If the source text matching Body is strict mode code, let Strict be true; else let Strict be false.
8. Set F.[[Strict]] to Strict.
9. If thisMode is lexical-this, set F.[[ThisMode]] to lexical.
10. Else if Strict is true, set F.[[ThisMode]] to strict.
11. Else, set F.[[ThisMode]] to global.
12. Set F.[[IsClassConstructor]] to false.
13. Set F.[[Environment]] to Scope.
14. Set F.[[PrivateEnvironment]] to PrivateScope.
15. Set F.[[ScriptOrModule]] to GetActiveScriptOrModule().
16. Set F.[[Realm]] to the current Realm Record.
17. Set F.[[HomeObject]] to undefined.
18. Set F.[[Fields]] to a new empty List.
19. Set F.[[PrivateMethods]] to a new empty List.
20. Set F.[[ClassFieldInitializerName]] to empty.
21. Let len be the ExpectedArgumentCount of ParameterList.
22. Perform ! SetFunctionLength(F, len).
23. Return F.
화살표 함수는 익명함수 형태로만 작성된다. 그래서 화살표 함수의 name 프로퍼티는 기본적으로 빈 문자열 형태로 지정된다.
(() => {}).name; // '' (빈 문자열)
변수에 할당하는 표현식으로 작성하게 되면, 평가되는 과정에서 식별자 이름을 name으로 넘겨준다. 그래서 변수 이름이 name으로 지정된다.
const fn = () => {};
fn.name; // 'fn'
InstantiateArrowFunctionExpression 과정 5번을 보면 파라미터 중 하나로 lexical-this를 넘긴다는 것 을 볼 수 있다.
이 때문에 ThisMode가 lexical로 설정되어 this가 구문적으로 감싸고 있는 함수의 this를 참조하게 된다.
또한 arguments, super, new.target 키워드도 바인딩되지 않는다