Arrow Function의 정의
- ES6 부터 추가 된 Function 표현 형태
- 일반 Function 표현에 비해 구문이 짧고 자신의 this, arguments, super 또는 new.target을 바인딩 하지 않음
- 항상 익명 함수의 형태
- 이 함수 표현은 메소드 함수가 아닌 곳에 가장 적합하며, 그래서 생성자로서 사용할 수 없음
기본 구문
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
(singleParam) => { statements }
singleParam => { statements }
() => { statements }
고급 구문
params => ({foo: bar})
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();
Function 표현과의 비교
var selected = allJobs.filter(function (job) {
return job.isSelected();
});
var selected = allJobs.filter(job => job.isSelected());
var total = values.reduce(function (a, b) {
return a + b;
}, 0);
var total = values.reduce((a, b) => a + b, 0);
Arrow Function 특징
짧은 함수
- 일반 Function 표현 보다 짧게 표현할 수 있음
var elements = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
elements.map(function(element) {
return element.length;
});
elements.map((element) => {
return element.length;
});
elements.map(element => {
return element.length;
});
elements.map(element => element.length);
elements.map(({ length: lengthFooBArX }) => lengthFooBArX);
elements.map(({ length }) => length);
바인딩 되지 않은 this
- 일반 Function 표현에서는 모든 새로운 함수가 자신의
this
값을 정의했음
- 함수 종류에 따라
this
가 가리키는 객체가 다름
- 생성자 : 새로운 객체
- strict 모드에서의 함수 : undefined
- 객체 메서드 : 베이스 객체
- callback 함수 : 전역 객체 window
- Arrow Function에서는 전역 컨텍스트에서 실행 될 때
this
를 새로 정의하지 않음
- 코드에서 바로 바깥의 함수(혹은 class)의
this
(Lexcial this) 값을 사용
this
를 클로저 값으로 처리하는 것과 같음
function Person() {
this.age = 0;
setInterval(function growUp() {
this.age++;
}, 1000);
}
var p = new Person();
function Person() {
var that = this;
that.age = 0;
setInterval(function growUp() {
that.age++;
}, 1000);
}
function Person(){
this.age = 0;
setInterval(() => {
this.age++;
}, 1000);
}
var p = new Person();
Arrow Function을 사용해서는 안되는 경우
메서드 (method)
- 메서드로 정의한 Arrow Function 내부의 this는 메서드를 소유한 객체, 즉 메서드를 호출한 객체를 가리키지 않고 상위 컨텍스트인 전역 객체 window를 가리킴
const person = {
name: 'Lee',
sayHi: () => console.log(`Hi ${this.name}`)
};
person.sayHi();
const person = {
name: 'Lee',
sayHi() {
console.log(`Hi ${this.name}`);
}
};
person.sayHi();
프로토타입 (prototype)
const person = {
name: 'Lee',
};
Object.prototype.sayHi = () => console.log(`Hi ${this.name}`);
person.sayHi();
const person = {
name: 'Lee',
};
Object.prototype.sayHi = function() {
console.log(`Hi ${this.name}`);
};
person.sayHi();
생성자 함수 (constructor)
- Arrow Function은 prototype 프로퍼티를 가지고 있지 않음
const Foo = () => {};
console.log(Foo.hasOwnProperty('prototype'));
const foo = new Foo();
addEventListener 함수의 callback 함수 (내부에서 this를 사용하는 경우)
- addEventListener 함수의 콜백 함수를 화살표 함수로 정의하면
this
가 상위 컨택스트인 전역 객체 window를 가리킴
var button = document.getElementById('myButton');
button.addEventListener('click', () => {
console.log(this === window);
this.innerHTML = 'Clicked button';
});
var button = document.getElementById('myButton');
button.addEventListener('click', function() {
console.log(this === button);
this.innerHTML = 'Clicked button';
});
호이스팅
Arrow Function의 호이스팅
console.log(x())
var x = () => {
return 100;
}
- 위의 코드를 실행하면 아래와 같은 에러가 발생
- 이건 Arrow Function 에서만 발생하는 에러는 아님
- 일반 Function의 경우에도 함수 표현식을 이용하는 경우, 함수의 선언 부분만 끌어 올리게 되어 동일한 에러가 발생
일반 Function의 호이스팅 비교
- 함수 선언문 : 함수 정의부만 존재하고 별도의 할당 명령이 없는 것
- 함수 표현식 : 정의한 함수를 별도의 변수에 할당하는 것
- 호이스팅 시 변수로 취급되어 선언 부분만 끌어 올림
console.log(x())
var x = function() {
return 100;
}
console.log(x())
var x = function y() {
return 100;
}
console.log(x())
function x() {
return 100;
}
출처