서론
오늘은 어제 과제 제출 당시에 개인과제의 JS파일이 한 개였어서 튜터님이 동작, 주제별로 나누는 것이 가독성이 더 좋은 코드가 될 것 같다고 피드백을 해주셨습니다. 이미 어제 JS코드를 나눠서 바로 제출했지만 제출 항목에 보완한 부분을 작성하라고 적혀있었고 코드를 주제별로 분리하면서 중복된 코드를 제거하고 함수 선언식과 함수 표현식 그리고 화살표 함수를 사용하고 있었기에 화살표 함수로 통일해서 보완했다고 작성했습니다.
그러면서 궁금증이 생겼는데 왜? 화살표 함수가 ES6문법에 새로 생겨난 이유가 무엇이고 화살표 함수의 장점과 만들어진 이유가 무엇인지 학습하기로 했습니다.
화살표 함수
// 화살표 함수의 기본 문법
let func = (arg1, arg2, ...argN) => expression
탄생 배경
ES6 이전에는 함수가 자신의 this를 바인딩하는 방식이 동적으로 결정되어 혼란을 야기하는 문제가 많았습니다. 함수가 객체의 메서드로 사용되는 경우나 콜백 함수로 전달되는 경우에 this가 예상과 다르게 동작하는 것을 방지하기 위해 ES6에 나온 것이 화살표 함수입니다
장점
- 간결성: 화살표 함수는 함수 표현식을 간단하게 만들어줍니다. 특히 단일 표현식을 반환하는 함수의 경우 중괄호와 return 키워드를 생략할 수 있어서 코드가 더 간결해집니다.
- 스코프: 화살표 함수는 자신의 this, arguments, super, new.target을 바인딩하지 않습니다. 함수가 정의된 시점에서 상위 스코프의 this를 그대로 유지합니다. 이로 인해 혼란을 줄이고 예측 가능한 동작을 제공합니다.
다른 특징으로는 생성자로서의 사용 불가: 화살표 함수는 생성자로 사용할 수 없습니다. 따라서 new 키워드를 사용하여 호출할 수 없으며, this가 정적으로 결정되기 때문에 프로토타입을 가지지 않습니다.
일반 함수 실행과 화살표 함수의 차이점: this 바인딩 여부
- 바인딩 있는 함수: 일반 함수는 호출될 때 실행 콘텍스트에 따라 this가 동적으로 바인딩됩니다. 이것은 함수가 호출될 때마다 this가 호출한 콘텍스트에 의해 결정된다는 것을 의미합니다.
- 바인딩 없는 함수: 화살표 함수는 자체적인 this 바인딩이 없습니다. 대신, 화살표 함수는 선언된 위치에서 외부 스코프의 this를 가리킵니다. 렉시컬 스코프에 의해 this가 정적으로 결정되기 때문에, 화살표 함수 내부에서 this는 항상 화살표 함수가 선언된 스코프의 this와 동일합니다.
예외 함수 addEventListner
콜백 함수도 일반 함수처럼 실행될 때 this는 전역 객체를 가리키지만 addEventListner()는 설계자가 해당 요소에 바인딩되어 있게 만들어서 addEventListner의 this는 이벤트 리스너가 등록된 DOM 요소를 가리킵니다.
위에서 말하는 this바인딩이란
this의 바인딩 : 함수가 호출될 때 this가 가리키는 대상을 결정하는 것
자바스크립트에서 this는 실행 컨텍스트에 의해 동적으로 결정되며, 함수가 어떻게 호출되느냐에 따라 달라집니다.
1. 암시적 바인딩(Implicit Binding)
const obj = {
name: 'John',
greet: function() {
console.log(`Hello, ${this.name}!`);
}
};
obj.greet(); // Hello, John!
메소드 호출 시 메서드가 속한 객체를 가리킵니다. 가장 일반적인 상황으로, 점 표기법 또는 대괄호 표기법을 사용하여 객체의 메서드를 호출할 때 발생합니다.
2. 명시적 바인딩(Explicit Binding)
function greet() {
console.log(`Hello, ${this.name}!`);
}
const obj = { name: 'John' };
greet.call(obj); // Hello, John!
greet.apply(obj, ['Hello']); // Hello, John!
const boundGreet = greet.bind(obj);
boundGreet(); // Hello, John!
call, apply, bind 메소드를 사용하여 this를 특정 값으로 명시적으로 바인딩이 가능합니다.
- call: 함수를 즉시 호출하면서 첫 번째 매개변수로 전달된 객체를 this로 설정합니다
- apply: call과 유사하지만 함수의 매개변수를 배열로 전달합니다
- bind: 함수를 호출하지 않고 this를 특정 객체에 바인딩한 새로운 함수를 생성합니다
3. 전역 객체(Global Object) 바인딩
전역 스코프에서 호출되는 함수의 경우, this는 전역 객체를 가리킵니다. 브라우저에서는 전역 객체가 window이며, Node.js에서는 global입니다.
4. 새로운 인스턴스 바인딩(New Binding)
function Person(name) {
this.name = name;
}
const john = new Person('John');
console.log(john.name); // John
생성자 함수를 사용하여 객체 인스턴스를 생성할 때, this는 새로운 인스턴스를 가리킵니다.
함수와 메서드의 차이
함수는 그 자체로 독립적인 기능을 수행하고 메서드는 자신을 호출한 대상 객체에 대한 동작을 수행합니다.
함수가 전역 스코프에서 호출될 때, this는 전역 객체를 가리킵니다.
메서드가 호출될 때, this는 해당 메서드를 호출한 객체를 가리킵니다.
결론
const obj = {
name: 'John',
greet: function() {
console.log(`Hello, ${this.name}!`);
}
};
// 함수 호출
obj.greet(); // 출력: Hello, Object!
// setTimeout 내부에서의 함수 호출 (화살표 함수)
setTimeout(() => obj.greet(), 1000); // 출력: Hello, John!
--------------------------------------------------------------------------------
// 일반 함수 this 동적 바인딩
const obj = {
name: 'John',
greet: function() {
console.log(`Hello, ${this.name}!`);
}
};
// 메서드 호출
obj.greet(); // 출력: Hello, John!
// setTimeout 내부에서의 메서드 호출 (일반 함수)
setTimeout(obj.greet, 1000); // 출력: Hello, undefined!
위 코드처럼 일반 함수는 this가 동적으로 변하면서 혼란을 야기하는 문제를 화살표 함수는 콜백 함수를 사용해도 this가 정적으로 상위 스코프를 가리켜서 문제를 해결할 수 있는 장점이 있었습니다.
'TIL' 카테고리의 다른 글
TIL - 비동기 데이터 처리 및 렌더링 (1) | 2024.05.02 |
---|---|
TIL - CSS와 친해지기 (0) | 2024.05.01 |
TIL - 모듈화(Modularization) 장점 및 주의사항 (0) | 2024.04.29 |
TIL - JS를 이용해서 무한 슬라이드(loop slide) 만들기 (0) | 2024.04.28 |
TIL - 자바스크립트의 이벤트 루프 이해 (1) | 2024.04.26 |