자바스크립트는 함수 안쪽에 또 다른 함수를 선언하는 중첩 함수(Nested Functions)가 가능하다.
자바스크립트가 함수를 변수와 같이 값(value)처럼 다루기 때문이다. (자바스크립트에선 같은 이름의 변수와 함수를 선언하는 것 불가능하다.)
또한 중첩 함수는 최상위 레벨에만 작성이 가능하다. if 또는 while문 등 문장에서 작성할 수 없다.
1. 클린 코드
//유저가 무직자인지 확인한다.
if(user.job == null){
...
}
if(user.isUnemployed()){
...
}
두 코드는 같은 행동을 나타낸다.
1번 코드 예제는 주석으로 의도를 명시했지만 2번 코드 예제는 코드 그 자체로 의도를 표현한다.
1번 코드와 같이 주석으로 설명하는 것이 많아지면 코드가 길어지고 가독성이 떨어진다.
즉, 단위 로직을 함수로 만드는 행위는 클린 코드에 도움되며 자바스크립트의 중첩 함수는 강력한 도구가 된다.
function foo(){
function bar(){
console.log('Hello');
}
bar(); //Hello 출력.
}
bar(); //에러발생, bar is not defined.
중첩 함수는 선언된 함수 내부가 아니면 호출할 수 없다.
bar함수를 foo함수 내부에 위치시킨다는건 bar함수는 foo함수 내부에서만 사용된다는 것을 명시한다.
접근제어자가 존재하는 Java도 한 Class내부에 여러 개의 public메서드가 존재하고 각 public메서드가 사용하는 private메서드가 존재한다면 어떤 private메서드가 어떤 public메서드와 어우러지는지 확인하기 어려운 경우가 있다. (이는 특정 public메서드에서만 사용되는 private 헬프 메서드가 많다라는건 객체의 응집도가 떨어진다는 신호이다.)
자바스크립트는 접근제어자가 없어도 공개적(public)으로 사용되는 함수와 함수를 도와주는 지역적 헬퍼 함수를 중첩 함수로 두면서 명확한 구분이 가능하다.
2. 성능
함수가 실행될 때 함수 내부에 존재하는 지역적인 변수들이 존재한다면 그 변수들은 함수가 실행될 때만 존재한다.
함수가 종료되면 지역적인 값들과 객체들은 사라진다.
중첩된 함수가 변수와 같이 값(valu)처럼 다뤄진다는 사실을 생각해보면 된다.
function foo(a, b){
function bar(){
return a + b;
}
return bar();
}
foo(1, 2);
foo함수가 실행될 때 bar함수 객체가 생성되고 실행된다.
foo함수가 종료되면 지역적인 함수 bar 객체는 사라진다. (만약 foo함수가 100번 실행 -> bar함수 객체는 100번 생성, 100번 파괴)
bar함수를 중첩시키지 않고 외부에 그대로 노출시킨다면?
function foo(a, b){
return bar(a, b);
}
function bar(a, b){
return a + b;
}
foo(1, 2);
foo함수가 여러번 호출되도 bar함수 객체는 딱 1번 만들어지고 계속 사용된다.
이런 이유로 중첩 함수를 사용하는건 성능상 약점을 가지게 된다.
하지만 이것은 오래전 이야기고 이미 최근 브라우저와 JS엔진들은 이런 상황을 내부적 최적화를 거쳐 성능차이가 없다.
3. 기능 - 클로저(closure)
클로저는 자바스크립트의 특징을 활용했다.
자바스크립트 함수의 지역적으로 선언된 값들은 함수가 종료되면 사라진다.
하지만 return을 활용해 내부의 값들을 외부로 노출시킬 수 있다. return문이 외부 스코프와 함수 내부를 이어주는 일종의 통로가 된다.
이것을 '클로저'라고 한다.
function foo(){
const name = "Nana";
function userName(){
alert(name);
}
return userName;
}
위 예제가 클로저 기법을 사용한 것이다. userName이라는 중첩 함수가 존재하고 return문을 통해 외부로 노출됐다.
이제 foo함수를 호출하면 중첩 함수인 userName함수도 호출이 가능하다.
중첩 함수는 클로저를 구성하는 핵심성분이다!
[출처]
https://siyoon210.tistory.com/162
'개발 > Javascript' 카테고리의 다른 글
[JS] 스택 / 큐 (0) | 2022.10.02 |
---|---|
[JS] mutable / immutable (1) | 2022.09.30 |
[JS] 배열 reduce 함수 (0) | 2022.09.27 |
[JS] 문자열 비교하기 (1) | 2022.09.24 |
[JS] 전개 구문 (Spread syntax) (1) | 2022.09.23 |