Development Study/Frontend

[JavaScript, React] const = () => {}? function () {}? 함수 표현식, 함수 선언문 중 무엇을 쓸까?

TMInstaller 2023. 5. 30. 11:14
728x90

자바스크립트에서 함수를 작성하는 방법은 여러 가지가 있습니다.
그 중에서도 함수 선언문, 함수 표현식, 그리고 화살표 함수에 대해 알아보겠습니다.
이들의 차이점은 무엇이고 어떤 상황에서 어떤 것을 사용하면 좋을까요?


1. 리액트에서의 함수 표현식과 선언문

리액트에서 컴포넌트 함수를 작성할 때, 함수 선언문과 함수 표현식 중 어떤 것을 사용해야 할까요?
여기에는 정답이 없지만, 두 방식 간의 차이점을 이해하고 상황에 맞게 적절하게 선택하는 것이 중요합니다.
 
함수 선언문(function () {})을 사용하면 메인 로직을 한눈에 보여주고, export default와 선언을 동시에 할 수 있습니다.
그런데 이 경우, 일반적인 자바스크립트에서 함수 표현식을 사용할 때의 장점을 일부 포기하게 됩니다.
 
반면, 함수 표현식(const = () => {})을 사용하면 일반적인 자바스크립트에서의 장점을 살릴 수 있습니다.
그러나 메인 로직에서만 함수 선언문을 사용하면 코드가 일관성이 떨어질 수 있습니다. 이는 함수 선언문과 함수 표현식이 혼용되어 사용되면서 발생하는 문제입니다.
 

그럼 함수 선언문과 표현식의 차이점은 무엇인가요?

JavaScript에서 함수 선언문과 함수 표현식은 비슷한 기능을 제공하지만, 중요한 차이점들이 있습니다.
이러한 차이점들은 각각의 사용에 영향을 미치며, 이에 따라 특정 상황에 더 적합하게 됩니다.
 
1. 함수 선언문 (Function Declarations):

function myFunction() {
    // function body
}

함수 선언문은 호이스팅 (hoisting)이 일어납니다.
이는 함수가 선언되기 전에 호출할 수 있음을 의미합니다.
이러한 특성은 큰 프로그램에서 유용할 수 있지만, 예상치 못한 동작을 유발할 수도 있습니다.
 
2. 함수 표현식 (Function Expressions):

let myFunction = function() {
    // function body
}

함수 표현식은 호이스팅되지 않습니다.
이는 함수가 선언되기 전에 호출할 수 없다는 것을 의미합니다.
또한 함수 표현식을 사용하면 함수를 변수에 할당할 수 있고, 이를 다른 함수에 인자로 전달하거나, 객체의 메소드로 사용하거나, 배열의 원소로 저장하는 등 더 많은 유연성을 제공합니다.
또한, 자바스크립트에서 함수 표현식은 익명 함수(이름 없는 함수)를 사용할 수 있게 해주는데, 이는 클로저, 콜백, 즉시 실행 함수 등에서 유용하게 사용됩니다.
 
함수 표현식을 사용하는 경우, 그 특정한 장점들을 활용할 수 있습니다.

  1. 익명 함수와 클로저
    •  함수 표현식은 익명 함수를 생성하거나 클로저를 사용하는데 유용합니다.
    • 클로저는 함수와 그 함수가 선언될 때의 렉시컬 환경과의 조합입니다.
    • 이는 함수가 자신이 선언된 스코프에서 액세스할 수 있었던 모든 변수를 '기억'하는 능력을 가집니다.
    • 이는 함수가 선언된 곳에서의 변수를 활용하는 데 매우 유용하며, 이러한 패턴은 모듈 패턴, 콜백, 이벤트 핸들러 등에서 자주 볼 수 있습니다.
  2. 변수로의 할당
    •  함수 표현식은 변수에 할당될 수 있기 때문에, 다른 함수의 매개변수로 전달하거나 다른 함수에서 반환하는 등의 동작이 가능합니다.
    • 이는 함수형 프로그래밍에서 매우 중요한 특성입니다.
  3. Arrow 함수
    •  Arrow 함수는 함수 표현식의 특별한 형태로, this 바인딩을 갖지 않는 것이 특징입니다.
    • 즉, Arrow 함수 내부에서 this를 참조하면, 해당 함수를 둘러싼 코드의 this를 가리킵니다.
    • 이러한 특성은 콜백 함수에서 매우 유용합니다.

 

따라서, 둘 중 어떤 것을 선택할지는 코드의 목적과 개인의 코딩 스타일에 따라 달라집니다.
일관성 있는 코드를 작성하려면 하나의 방식을 선택하여 일관되게 사용하는 것이 좋습니다.

2. this에 대한 이해

자바스크립트에서 this는 상당히 복잡하게 작동합니다.
함수의 유형에 따라 this가 어떻게 작동하는지 알아봅니다.

1) 일반 함수에서의 this

  • 전역 함수에서: 함수를 호출하면 기본적으로 전역 객체를 가리킵니다. (일반적으로 window 객체)
  • 메소드 함수에서: 메소드 함수를 호출하면 메소드를 소유한 객체를 가리킵니다.
  • 생성자에서: 생성자를 호출하면 새로 생성된 인스턴스를 가리킵니다.

2) 화살표 함수에서의 this

  • 화살표 함수에서는 자체적으로 가리키는 this가 없습니다. 대신 상위 스코프의 this를 가리킵니다.

조금 더 자세히 알아볼까요?
먼저, JavaScript에서 this는 실행 컨텍스트에 따라 동적으로 결정되는 특수한 변수입니다.
이를 이해하기 위해 다음의 경우들을 자세히 살펴보겠습니다.

1. 일반 함수에서의 this

  • 전역 함수에서
    • JavaScript에서 함수를 전역 스코프에서 호출하면, this는 전역 객체를 가리킵니다.
    • 웹 브라우저에서는 전역 객체가 window입니다.
function globalFunction() {
  console.log(this); // 'this'는 window 객체를 가리킨다.
}

globalFunction(); // 로그: Window {...}
  • 메소드 함수에서: 객체의 메소드로 함수를 호출하면, this는 그 함수를 호출한 객체를 가리킵니다.
const myObject = {
  property: 'I am an object property',
  method: function() {
    console.log(this.property); // 'this'는 myObject를 가리킨다.
  }
}

myObject.method(); // 로그: "I am an object property"
  • 생성자에서: new 키워드로 생성자 함수를 호출하면, this는 생성된 인스턴스를 가리킵니다.
function MyConstructor() {
  this.property = 'I am an instance property';
}

const newInstance = new MyConstructor();
console.log(newInstance.property); // 로그: "I am an instance property"

2. 화살표 함수에서의 this

화살표 함수(arrow function)는 자체적으로 this 바인딩을 생성하지 않습니다.
대신, 화살표 함수는 this 값을 감싸는 (즉, 둘러싼) 함수나 코드의 this를 가리킵니다.
이를 렉시컬 바인딩(lexical binding)이라고 부릅니다.

const myObject = {
  property: 'I am an object property',
  method: function() {
    // 화살표 함수 내부에서의 'this'는 method를 둘러싼 함수의 'this'를 가리킵니다.
    const arrowFunction = () => console.log(this.property);
    arrowFunction();
  }
}

myObject.method(); // 로그: "I am an object property"

여기서 arrowFunction 내의 this는 method 함수의 this를 가리킵니다.
이것은 method 함수가 호출되면 myObject를 가리키기 때문에, arrowFunction에서의 this 역시 myObject를 가리키게 됩니다.
이렇게 this가 동작하는 방식은 JavaScript에서 중요한 개념입니다.
이는 함수가 어떻게 호출되는지에 따라 this의 값이 달라지기 때문입니다.
이러한 이유로 this를 사용할 때는 항상 주의해야 합니다.


3. Arguments에 대한 이해

  • 일반 함수에서: arguments를 사용할 수 있습니다. 이는 함수가 호출될 때 전달된 인자들의 정보를 담고 있는 객체입니다.
  • 화살표 함수에서: 화살표 함수에서는 arguments를 사용할 경우 에러가 발생합니다. 화살표 함수에서는 대신 rest 파라미터를 사용하여 arguments를 대체할 수 있습니다.

4. 생성자 함수의 사용

  • 일반 함수에서: 생성자 함수를 사용할 수 있습니다. 이는 new 키워드와 함께 함수를 호출하여 새 객체를 생성하고 초기화하는 데 사용됩니다.
  • 화살표 함수에서: 화살표 함수에서는 this가 렉시컬 스코프를 가리키기 때문에 생성자 함수를 사용할 수 없습니다.

함수 선언문, 함수 표현식, 화살표 함수의 가장 큰 차이점은 this입니다.
일반 함수는 동적으로 this가 결정되지만, 화살표 함수는 정적으로 this가 결정됩니다.
따라서 이벤트 호출이나 콜백 함수를 사용할 때 this를 어떻게 사용하냐에 따라 적절한 함수를 선택할 수 있습니다.

+ 최신 버전의 JS에서 export const도 지원한다고 합니다. 이제 선택할 때 고려할 부분이 하나 줄었네요!


End
 
References

더보기
728x90