자바스크립트는 유연한 언어이다. 따라서 다른 일반적인 언어(Java, C)와 다르게, 함수를 선언하고 사용하는데 있어 굉장한 자유로움이 주어진다. 이는 능숙한 사람에게는 굉장한 이점으로 주어질 수 있지만, 미숙한 사람에게는 넘어야 할 허들이 되기도 한다. 자바스크립트에서 함수 선언 방식은 기본적으로 일반 함수와 익명 함수로 나눌 수 있다.
1. 일반 함수
일반적으로 다른 언어에서 사용하는 함수와 동일하다. 사용방식 또한 동일하며, 코드를 조금이라도 읽을 수 있는 사람이라면 매우 쉽게 이해할 수 있는 함수이다. 일반 함수는 다른 말로 함수 선언식이라고도 할 수 있다.
function 함수명(){
함수 로직
}
// 예시
function SayHello(){
console.log("hello!");
}
SayHello(); // 출력: hello!
일반 함수는 자바스크립트가 처음 읽힐 당시에 해석되므로, 함수가 쓰여진 위치가 상관없다.
이를 호이스팅이라고 하는데, 호이스팅이란 쉽게 말해 자바스크립트가 처음 읽힐 당시에 모든 객체(변수, 함수)의 선언부를 맨 위로 끌어올리는 것이다.
일반 함수는 함수 전체(함수명, 함수바디)가 통째로 호이스팅 되어 맨 위로 올라가기 때문에 위치 상관없이 읽을 수 있는 것이다.
SayHello(); // "hello!" 가 정상적으로 출력됨.
function SayHello(){
console.log("hello!");
}
SayHello(); // "hello!" 가 정상적으로 출력됨.
// 호이스팅 된 모습
//
// function SayHello(){ <- 함수 선언이 먼저 일어나고,
// console.log("hello!");
// }
//
// SayHello(); <- 첫 번째 SayHello();
// SayHello(); <- 두 번재 SayHello();
2. 익명 함수
우선 익명함수 자체는 다음과 같은 형태를 가지고 있다. 일반 함수와 비교하여보면, 함수의 이름이 존재하지 않는다.
function() {
console.log("hello!");
}
익명 함수는 재사용 하지 않는, 한번만 사용할 함수를 위한 개념으로, 따로 함수의 이름을 갖지 않는다. 리터럴(Literal) 방식으로 변수에 담겨 사용하는 함수이다. ("함수의 이름 != 변수" 임을 확실히 이해해야한다.)
리터럴(Literal) 방식이란 글자 뜻 그대로 "문자 그대로 읽히는 방식"을 의미하며, 일반적으로 변수에 데이터를 넣을 때 사용하는 방식이 리터럴 방식이다.
// 리터럴 방식
let a = 10;
const b = 20;
리터럴 방식으로 사용되는 익명 함수는, 변수에 저장되게 된다.
//익명 함수
const sayHello = function() {
console.log("hello!");
}
sayHello(); // 출력: hello!
다시 한번 말하지만, 함수가 이름을 갖는 것과 변수에 저장되는 것은 다르다.
이 차이점은 어디서 오냐면, 위에서 언급한 호이스팅의 개념에서 온다.
위의 일반함수의 경우, 함수 전체가 전부 맨 위로 올라가므로 함수를 호출하는 위치에 상관없이 사용될 수 있다고 했다.
반면, 리터럴 방식으로 사용되는 익명 함수의 경우, 호이스팅 시 함수를 담는 변수의 선언부만 위로 올라가고, 익명 함수 자체는 변수가 호출되었을 때 실행되기 때문에, 선언부가 호출 위치보다 위에 있어야 한다. 코드로 보면 다음과 같다.
//익명 함수
sayHello(); // Uncaught ReferenceError: Cannot access 'sayHello' before initialization
let sayHello = function() {
console.log("hello!");
}
sayHello(); // 위에서 에러가 났으니 출력이 나오지 않음
// 이 자바스크립트를 읽을 때(호이스팅 된 모습)
//
// const sayHello;
//
// sayHello(); <- sayHello의 초기화가 진행되지 않았다.
//
// sayHello = function(){
// console.log("hello!");
// }
//
// sayHello(); <- 초기화는 진행된 후 불렸으니, 원래대로라면 출력 가능
3. 결론
1) 일반 함수는 전역적이며, 전체가 다 호이스팅 되므로 호출의 위치와 구현의 위치간에 연관관계가 없다. 또한, 재사용될 기능에 주로 사용된다.
2) 익명 함수는 선언부만 호이스팅되며 호출의 위치와 구현의 위치간에 순서가 알맞아야 하고, 한번만 사용하는 기능에 사용된다.
위 말만 보면 익명 함수가 오히려 번거로운 것처럼 보일 수 있지만, 이는 메모리 관리에 효과적인 방안이 될 수 있다.
일반 함수는 자바스크립트를 초기에 읽어올 때 모두 호이스팅된다고 하였다.
만약, 전체 자바스크립트 내에서 단 한번만 쓰이는 함수가 일반 함수로 구현되어 있다고 가정해보자.
이 함수는 자신이 사용될 단 한번을 기다리며 불필요하게 메모리를 차지하고 있어야 한다. 메모리 사용량이 성능에 중요한 영향을 미칠 수 있는 웹 애플리케이션에서, 이는 메모리 낭비라고 볼 수 있다.
따라서 단 한번만 사용되는(재사용이 필요없는) 함수의 경우, 불필요한 시간동안 메모리를 차지하지 않도록 익명함수로 구현한다면, 정확히 해당 함수가 필요한 위치에서만 해당 함수가 구현되고 사라지면서 메모리를 아낄 수 있게 된다.
'Script > JavaScript' 카테고리의 다른 글
[JavaScript] Chapter 37. 자바스크립트의 private (0) | 2023.03.30 |
---|---|
[JavaScript] Chapter 36. 고차 함수와 콜백(Callback) – 일급 객체란 (0) | 2023.02.07 |
[JavaScript] Chapter 34. 맵 객체(Map Object) (0) | 2023.01.16 |
[JavaScript] Chapter 33. 객체 복사하기 - 앝은 복사, 깊은 복사 (0) | 2023.01.16 |
[JavaScript] Chapter 32. Clean Code 작성법 (0) | 2023.01.12 |
댓글