일반함수와 화살표 함수의 차이점을 보도록 하자.
const jonas = {
firstName: 'Jonas',
year: 1991,
calAge: function () {
console.log(this);
console.log(2037 - this.year);
},
greet: () => console.log(`Hey ${this.firstName}`),
};
jonas.greet();
위의 코드를 보자. console.log(Hey ${this.firstName})
가 Hey undefined
가 나온다. 그 이유는 greet 메서드가 화살표 함수로 정의되어 있기 때문이다. 화살표 함수는 독자적인 this 키워드를 가지고 있지 않다. 그 대신 화살표 함수가 정의된 주변 스코프에서 this를 찾고 그 값을 가지게 된다. 여기서는 greet 메서드가 jonas 객체 안에 있지만, 화살표 함수의 특성 때문에 this가 jonas 객체를 가리키지 않고, 상위 스코프인 전역 스코프의 this 값을 찾는다. 전역 스코프에서는 브라우저 환경에서 window 객체를 가리키게 되는데, window 객체에는 firstName이라는 속성이 없기 때문에 undefined가 나오게 된다. 만약 여기서 greet함수를 일반 함수로 정의하면 this가 jonas 객체를 가르키게 된다.
var firstName = 'Matilda';
const jonas = {
firstName: 'Jonas',
year: 1991,
calAge: function () {
console.log(this);
console.log(2037 - this.year);
},
greet: () => {
console.log(this);
console.log(`Hey ${this.firstName}`);
},
};
jonas.greet();
이 경우, var firstName = 'Matilda';
를 사용하여 window 객체에 firstName 속성을 추가할 수 있지만(이전 포스트에서 설명한 바 있다. var를 써주면 윈도우 객체에 이렇게 추가되어 있다 firstName: "Matilda"
) , 이러한 방법은 좋지 않다. var는 전역 객체에 속성을 추가하기 때문에, 이를 통해 해결할 수 있지만 코드의 복잡성과 유지보수성에 문제를 일으킬 수 있기 때문이다. 따라서, 화살표 함수와 var를 메서드로 사용하는 것보다는 일반 함수를 사용하는 것이 더 좋다.
일반 함수는 this를 바인딩할 수 있기 때문에 undefined 문제를 방지할 수 있다.
const jonas = {
firstName: 'Jonas',
year: 1991,
calAge: function () {
// console.log(this);
console.log(2037 - this.year);
const isMillenial = function () {
console.log(this);
console.log(this.year >= 1981 && this.year <= 1996);
};
isMillenial();
},
jonas.calcAge();
위의 코드에서 isMillenial 함수 안의 console.log(this);는 undefined가 출력된다. 이유는 isMillenial 함수가 strict mode에서 호출되기 때문에 this가 undefined로 바인딩되기 때문이다. isMillenial 함수는 calAge 메서드 안에서 정의되었지만, calAge 메서드가 아닌 독립적인 일반 함수로 호출되므로 this는 객체를 가리키지 않는다.
const jonas = {
firstName: 'Jonas',
year: 1991,
calAge: function () {
// console.log(this);
console.log(2037 - this.year);
const self = this;
const isMillenial = function () {
console.log(self);
console.log(self.year >= 1981 && self.year <= 1996);
// console.log(this.year >= 1981 && this.year <= 1996);
};
isMillenial();
},
위와 같이 calAge 메서드 밖에서 const self = this;를 사용하면 self는 calAge 메서드의 this를 참조하게 된다. 따라서, self는 jonas 객체를 가리키게 된다. 이렇게 하면 isMillenial 함수에서 self를 사용하여 올바르게 jonas 객체의 속성에 접근할 수 있다.
두 번째 방법은 화살표 함수를 사용하는 것이다. 화살표 함수는 독자적으로 this를 가지지 않으므로 상위 스코프의 this를 상속받는다.
const isMillenial = () => {
console.log(this);
console.log(this.year >= 1981 && this.year <= 1996);
// console.log(this.year >= 1981 && this.year <= 1996);
};
isMillenial();
},
위의 코드처럼 화살표 함수로 isMillenial을 정의하면, calAge 메서드의 this를 상속받기 때문에 this는 jonas 객체를 가리키게 된다.
다음으로 arguments 키워드에 대해 알아보자.
const addExpr = function (a, b) {
console.log(arguments);
return a + b;
};
addExpr(2, 5);
addExpr(2, 5, 8, 12);
var addArrow = (a, b) => {
console.log(arguments); //error
return a + b;
};
addArrow(2, 5, 8);
arguments 키워드는 오직 일반 함수에서만 존재하며, 화살표 함수에서는 사용할 수 없다.
화살표 함수에서 arguments를 사용하려고 하면 에러가 발생한다.