티스토리 뷰
일단 우리는 이미 함수를 만드는 방법을 잘 알고 있습니다.
// 함수를 만드는 방법
function 함수이름(파라미터) {
동작
return 리턴값
}
function이라는 키워드 다음에 함수 이름을 쓰고 소괄호 열고 닫은 다음, 다시 또 중괄호를 열어두면서 그 안에 필요한 동작들을 작성하는 것이죠. 그리고 함수를 호출할 때 어떤 값을 전달해서 함수가 동작할 때 그 값을 사용하게 하고 싶다면 이 소괄호 안에 파라미터를 작성할 수도 있죠.
그리고 함수가 호출된 자리에 되돌려 줄 값이 필요하다면 이 안에서 return 키워드를 통해서 리턴값을 작성해 줄 수도 있습니다.
아무튼 이렇게 function 키워드로 시작해서 함수를 만드는 방식을 함수 선언(Function Declaration)이라고 하는데요.
// 함수를 만드는 방법
const printCode = function () {
console.log('쑥쑥');
}
printCode();
함수를 만드는 방법은 함수 선언 말고도 한 가지가 더 있습니다.
바로 이 함수 선언을 변수에 할당하는 방식인데요. 이처럼 printCode라는 변수에 함수 선언을 값처럼 할당하고 있습니다. 코드를 실행했을 때도 잘 동작하는 모습을 확인할 수 있는데요.
이렇게 함수 선언을 값처럼 활용하는 방식을 가리켜서 함수 표현식(Function Expression)이라고 부릅니다.
여기서 한 가지 주의할 부분은 간혹 이렇게 함수 선언을 변수에 할당하는 모습만 함수 표현식이라고 오해하는 경우가 있는데요.
// 함수를 만드는 방법
const myBtn = document.querySelector('#myBtn');
myBtn.addEventListener('click', function () {
console.log('button is clicked!');
});
이전에 이벤트를 만들 때 addEventListener의 두 번째 파라미터로 함수를 선언해서 전달한 이 모습도 결과적으로는 함수 선언을 값처럼 활용한다는 점에서 함수 표현식이라고 할 수가 있는 겁니다.
다시 정리하면 함수 표현식은 변수에 할당하는 것이 포인트가 아니라 함수 선언을 값처럼 사용하는 방식이라는 점을 잘 기억해 주시면 좋을 것 같습니다.
자 그럼 함수 선언과 함수 표현식은 서로 어떤 차이가 있을까요?
// 함수를 만드는 방법
printCode(); // 쑥쑥
function printCode() {
console.log('쑥쑥');
}
우리가 그동안 사용하던 함수 선언 방식은 사실 선언을 하기 전에 호출할 수가 있었습니다.
코드를 실행해보면 분명히 함수 선언보다 먼저 함수를 호출했는데도 아무런 문제없이 코드가 잘 동작하는 모습을 확인할 수 있는데요. 이렇게 선언문이 위쪽으로 끌어 올려지는 현상을 호이스팅(Hoisting)이라고 배웠습니다.
// 함수를 만드는 방법
printCode(); // ReferenceError
const printCode = function () {
console.log('쑥쑥');
}
반면에 일반적으로 변수에 할당해서 함수를 만드는 함수 표현식은 변수의 특성상 선언 이전에 접근을 할 수가 없습니다.
에러가 발생하는 모습을 확인할 수 있습니다.
또 한 가지는 스코프의 차이가 있습니다.
// 함수를 만드는 방법
function printCode() {
function printJS() {
console.log('JavaScript');
}
console.log('쑥쑥');
printJS();
}
printCode();
printJS() // ReferenceError
함수 선언은 변수의 var 키워드처럼 함수 스코프를 가집니다.
이렇게 함수 안에 선언된 함수는 함수 밖에서 호출할 수 없지만,
// 함수를 만드는 방법
const x = 4;
if(x < 5) {
function printJS() {
console.log('JavaScript');
}
}
{
function printCode() {
console.log('쑥쑥');
}
}
printCode(); // 쑥쑥
printJS(); // JavaScript
만약에 이런 식으로 함수가 아닌 다른 코드 블록에서 함수 선언을 하게 되면 모두 전역적으로 호출이 가능해집니다.
// 함수를 만드는 방법
var printJS = function () {
console.log('JavaScript');
};
let printHi = function () {
console.log('Hi');
}
const printCode = function () {
console.log('쑥쑥');
}
반면에 함수 표현식의 경우에는 할당된 변수에 따라 스코프가 결정됩니다.
그러면 함수를 만들 때 둘 중 어떤 방식을 활용하는 것이 좋을까요?
코드의 가독성 면에서 변수 선언과 함수 선언 부분을 명확하게 구분할 수 있고 함수를 호출할 때도 자유로운 위치에서 함수를 호출할 수 있다는 점을 장점으로 함수 선언 방식을 권장하는 의견도 있고,
반드시 선언 이후에 호출할 수 있다는 점이 가독성 면에서는 오히려 코드의 흐름을 더 쉽게 파악할 수 있고 변수의 스코프도 활용할 수 있다는 부분을 장점으로 함수 표현식을 권장하는 의견도 있습니다.
둘 중 어느 방식을 선택하더라도 크게 문제되지는 않겠지만 두 방식이 서로 다른 특성을 가지고 있는 만큼 가급적 둘 중 하나를 선택해서 최대한 일관된 방식으로 함수를 만드는 것이 좋은데요.
일반적으로 어떤 개념을 설명할 때는 함수 표현식보다는 선언 부분이라는 의미가 좀 더 명확하게 구분되는 함수 선언이 보편적으로 사용되기 때문에 함수 표현식보다는 함수 선언을 우선적으로 사용할 것 같습니다.
'프론트엔드 > JavaScript' 카테고리의 다른 글
[함수 다루기] 04. 즉시 실행 함수(IIFE) (0) | 2022.12.25 |
---|---|
[함수 다루기] 03. 이름이 있는 함수 표현식 (0) | 2022.12.25 |
[자바스크립트의 동작 원리] 13. 종합 정리 (0) | 2022.12.24 |
[자바스크립트의 동작원리] 11. 변수와 스코프 (0) | 2022.12.24 |
[자바스크립트의 동작 원리] 10. null 병합 연산자 ?? (0) | 2022.12.24 |
- Total
- Today
- Yesterday
- findindex
- 동적(dynamic) 언어
- find
- 얕은복사
- redux-middleware
- some
- redux-thunk
- 비교 연산자
- redux thunk
- 참조형 데이터
- EVERY
- redux
- filter
- foreach
- redux middleware
- 느슨한 타입(loosely typed)
- 기본형 데이터
- undefined
- 불변 객체
- null
- 타입변환
- map
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |