모던 자바스크립트 Deep Dive - 6

2023. 3. 29. 10:58개발 관련 책 읽기/모던 자바스크립트 Deep Dive

✅ 아래 내용들에 대해서 알아보자

- 함수
- 함수의 여러 가지 종류
- 정리

 

함수

 함수는 JS에서 가장 중요한 핵심 개념으로 잘 이해하고 넘어가자. 쉽게 이야기하면 입력 -> 연산 -> 출력하는 일련의 과정을 말한다.

 

 

함수 선언문 방식

  • 함수 선언문은 함수 이름 생략 불가
  • 함수 선언문은 표현식이 아닌 문이다. 따라서 크롬 개발자 도구에서 undefined로 출력된다.
function add(x,y){
    return x + y;
}

  

function empty(){
    return; //반환문 생략 시 undefined 반환
}

console.log(empty());   //undefined

 

 

JS에서는 생성된 함수를 호출하기 위해 함수 이름과 동일한 식별자를 암묵적으로 생성하고, 거기에 함수 객체를 할당한다.

즉, 함수는 함수 이름으로 호출하는 것이 아니라 함수 객체를 가리키는 식별자로 호출한다.

 

아래 코드를 보면 함수 이름으로 호출하는 거면 add(1,2)가 되어야 하지만 식별자인 add2(1,2)로 함수를 호출하게 된다!

결론적으로 JS 엔진은 함수 선언문을 함수 표현식으로 변환해 함수 객체를 생성한다고 생각할 수 있다.(단, 함수 선언문과 표현식이 정확히 동일하게 동작하는 것은 아니다!)

//함수 표현식 방식
add2=function add(x,y){
    return x + y;
}

console.log(add2(1,2));

 

 

 

 

함수 표현식

  • JS에서 함수는 객체 타입의 값이다. 따라서 변수에 할당할 수도 있고 프로퍼티 값도 할당할 수 있다.
  • 이처럼 값의 성질을 갖는 객체를 일급 객체라 한다. -> 함수를 값처럼 자유롭게 사용할 수 있다는 의미
  • 함수 호이스팅은 함수를 호출하기 전에 반드시 함수를 선언해야 한다는 당연한 규칙을 무시하므로 함수 선언문 대신 함수 표현식을 사용할 것을 권장한다.
add=function add(x,y){
    console.log("add origin")
    return x + y;
}

console.log(add(1,2));

 

 

Function 생성자 함수

  •  JS가 기본 제공하는 빌트인 함수인 Function 생성자 함수로 함수를 생성할 수 있다.
  • Function 생성자 함수로 생성하는 방식은 일반적이지 않고 바람직하지도 않다. -> 권장하는 방법 아님
let mul = new Function('x','y','return x*y');
console.log(mul(1,2))

 

 

화살표 함수(ES6)

  • ES6에서 도입된 화살표 함수는 function 키워드 대신 화살표(=>)를 사용해 좀 더 간략한 방법으로 함수를 선언할 수 있다.
  • 화살표 함수는 표현만 간략한 것이 아니라 내부 동작 또한 간략화되어 있다.(생성자 함수로 사용할 수 없고, 기존 함수와 this 바인딩 방식이 다르고, prototype 프로퍼티가 없으며, arguments 객체를 생성 안 함)
const lambdaAdd=(x,y)=> x+y;
console.log(lambdaAdd(1,2));

 

 

즉시 실행 함수

 함수 정의와 동시에 즉시 호출되는 함수를 즉시 실행 함수(Immediately Invoked Function Expression)라고 한다. 즉시 실행 함수는 단 한 번만 호출되며 다시 호출할 수 없다.

(function (){
    var a = 3;
    var b = 5;
    console.log("즉시 실행 함수")
    return a * b;
}());

 

 

재귀 함수

 재귀함수는 자기 자신을 호출하는 함수로 탈출 조건이 없으면 스택 오버플로 에러가 발생하게 되니 주의해서 사용해야 한다.

//비재귀 방식
function countdown(n){
    for(var i=n;i >=0;i--) console.log(i);

}

console.log(countdown(10));

//재귀 방식
function countdownRecursive(n){
    if(n <0) return;
    console.log(n);
    countdownRecursive(n-1);
}

//재귀식 팩토리얼 함수
function factorial(n){
    if(n<=1)
        return 1;
    return n*factorial(n-1);
}

console.log(factorial(3));

 

 

중첩 함수

 함수 내부에 정의된 함수를 중첩 함수 또는 내부 함수라 한다. 중첩 함수를 포함하는 함수는 외부 함수라 부른다.

//외부 함수
function outer(){
    var x=1;

    //중첩 함수
    function inner(){
        var y=2;

        //외부 함수의 변수를 참조할 수 있다
        console.log("inner func = ",x+y);
    }

    inner();
}

outer();

 

 

콜백함수/고차함수

함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수를 콜백 함수라고 하며, 매개변수를 통해 함수의 외부에서 콜백 함수를 전달받은 함수를 고차함수 라고 한다. 매개변수를 통해 함수를 전달받거나 반환값으로 함수를 반환하는 함수를 함수형 프로그래밍에서 고차함수라 한다.

//고차함수
function repeatFunc(n,f){
    for(var i=0;i<n;i++){
        f(i);
    }
}

//콜백함수
var logAll=function (i){
    console.log(i)
};

repeatFunc(5,logAll);   // 0, 1, 2, 3, 4

//콜백함수
var logOdds=function(i){
    if(i % 2) console.log(i);
};

repeatFunc(5,logOdds) // 1, 3

 

 

순수 함수/비순수 함수

 함수형 프로그래밍에서는 어떤 외부 상태에 의존하지도 않고 변경하지도 않는, 즉 부수 효과가 없는 함수를 순수 함수라고 하고, 외부 상태에 의존하거나 외부 상태를 변경하는, 즉 부수 효과가 있는 함수를 비순수 함수라고 한다.

 

순수 함수

  • 동일한 인수가 전달되면 언제나 동일한 값을 반환하는 함수다. 즉 어떤 외부 상태에도 의존하지 않고 오직 매개변수를 통해 함수 내부로 전달된 인수에게만 의존해 값을 생성해 반환한다. 함수의 외부 상태에 의존하는 함수는 외부 상태에 따라 반환값이 달라진다(전역 변수, 서버 데이터, 파일 DOM 등..)
  • 일반적으로 최소 하나 이상의 인수를 전달받는다. 인수를 전달받지 않는 순수 함수는 언제나 동일한 값을 반환하므로 상수와 같다. 따라서 최소 하나이상의 인수를 전달받고 인수를 변경하지 않는 것이 기본이다. 순수 함수는 인수의 불변성을 유지한다.
  • 외부 상태를 변경하지 않고 의존하지도 않는다.
//increase는 동일한 인수가 전달되면 언제나 동일한 값을 반환한다.(순수 함수)
function increase(n){
    return ++n;
}

count = increase(count);
console.log(count); //1

count = increase(count);
console.log(count); //2

 

 

비순수 함수

  • 외부 상태에 따라 반환값이 달라지고, 외부 상태에 의존하는 함수를 비순수 함수라고 한다.
  • 순수 함수와 다르게 외부 상태를 변경하는 부수 효과(side effect)가 있다.

var count =0;

//비순수함수
function increase(){
    return ++count; //외부 상태에 의존하며 외부 상태를 변경한다. -> 전역변수 count 변경한다.
}

increase();
console.log(count); //1

increase();
console.log(count); //2

 

 

정리

  • 함수가 외부 상태를 변경하면 상태 변화를 추적하기 어려워진다. 따라서 비순수 함수 사용을 지양하고, 순수 함수를 사용하는 것이 좋다. 
  • 함수형 프로그래밍은 순수 함수와 보조 함수의 조합을 통해 외부 상태를 변경하는 부수 효과를 최소화해서 불변성을 지향하는 프로그래밍 기법이다. 로직 내 존재하는 조건문/반복문을 최소화해서 복잡성을 해결하며, 변수 사용을 최소화하고 상태 변경을 최소화하여 프로그램 안정성을 높이는 패러다임이다.
반응형