본문 바로가기

Coding Language/JavaScript

[JavaScript] JavaScript 함수 다루기

[해당 포스트는 개인적으로 공부를 하고 차후에 참고용으로 하고자 작성한 것입니다.
따라서 잘못된 부분이나 부족한 부분이 있을 수 있기에 참고하시기 바랍니다.]

이번 시간엔 함수를 다루는 방법과, 이것을 호출하는 방법, Lambda방식 등 JavaScript 함수 처리에 대해 기본적으로 다뤄볼 것이다.

- 함수의 기본 형식

함수를 생성하는 방법은 3가지 존재한다.

첫 번째로 function을 선언하고 함수를 정의하는 방법이다.

 

function f1(){
    console.log("Hello World!");
}

 

이러한 방식을 이용했을 때 Hoisting개념을 적용시킬 수 있다. Hoisting은 선언과 사용을 순서에 상관없이 사용할 수 있다. 간단하게 설명하자면 다음의 코드를 보자.

 

f1();

function f1(){
    console.log("Hello World!");
}

f1();

 

이렇게 함수를 선언하기 전에 f1에 대한 함수를 호출해도 문제없이 잘 작동한다.

 

두 번째로 변수를 선언하고 함수를 정의하는 방법이다.

 

const f2 = function(){
    console.log("Hello World2!");
}

 

JavaScript에서 함수는 보통 const Type으로 설정하여 함수가 변경되지 않도록 설정한다고 한다. 이후 f2() 형태로 호출하면 함수가 작동한다.

! 주의 문제는 여기선 Hoisting 개념이 적용이 안된다. 첫 번째에서 했던 방식으로 처리하면 Error가 난다.

세 번째로 변수를 선언하고 Lambda를 정의하는 방법이다.

 

const f3 = () => {
    console.log("Hello World3!");
}

 

서로 편한 방식으로 함수를 선언해서 사용하면 되지만, 주로 Lambda방식을 자주 사용한다고 하니까 자주 이용하도록 하자.

- 함수의 인수, Return 처리

여기도 3가지 상황이 존재한다.

첫 번째로 인수 전달이 없고 Return값이 없는 형태이다.

 

function f1(){

}

 

위에서 작성했던 방법과 동일하다.

 

두 번째로 인수 전달이 있고 Return값이 없는 형태이다.

 

function f2(a, b){
    console.log('a =', a);
    console.log('b =', b);
}
f2(10, '호랑이');

 

Java와 다르게 인자의 Type은 따로 정하지 않는다. 편하게도 인자의 Type에 맞게 알아서 처리해주기 때문에 호출할 때, 값만 넣으면 된다.

 

세 번째로 인수 전달이 있고 Return값이 있는 형태이다.

 

function f3(a){
    console.log('function3 Call.', a);
    return 100;
}
let n = f3(50);
console.log(n);

 

return 하여 저장할 변수를 선언하고 log를 통해 출력하면 return 된 값을 볼 수 있다.

그렇다면 이번엔 Lambda방식을 이용하여 인자와 return을 처리해보도록 하자.

- Lambda식을 이용한 함수의 인수, return 처리

1번째 항목에서 Lambda함수를 선언하는 방식에 대해서 확인하였다. 이번엔 인자를 넣거나 return을 처리할 수 있도록 만들어보자. 생각보다 정말 단순하다.

 

const f3 = (m ,n) => {
    return m + n;
}
console.log(f3(10, '호랑이'));

 

첫 괄호에 받을 인자를 선언하고, return으로 반환해주면 된다.

여기서부터 중요한 개념이 나온다. Lambda 식은 슈가 코드 방식의 끝판을 보여주기 때문에 생략할 수 있는 게 많다.

Java의 Lambda식 포스팅한 것과 같이 줄이는 방법은 비슷하다.

 

첫 번째로 함수 인자가 1개 일 때, 괄호를 생략할 수 있는 특징이 있다.

 

const f1 = num => {
    console.log("function1 Call.");
    console.log(num);
}
f1(10);

 

num주위에 ()가 없는 것을 알 수 있다. 이처럼 인자가 1개일 땐 괄호를 생략해서 쓴다.

 

두 번째로 처리할 명령이 한 줄일 경우, {} (Scope)와 return을 생략할 수 있는 특징이 있다.

//변경 전
const f2 = () => {
    return 100;
}

//변경 후
const f2 = () => 100;

둘 다 똑같은 처리를 한다. 이러한 문법은 자주 출현하기 때문에 미리 알아둬야 할 필요가 있을 것이라 한다.

- Lambda 함수를 이용한 예제

함수 f4가 a와 b의 정보를 가지고 있는 객체를 return 한다고 가정하자. 그럼 코드는 다음과 같다.

 

const f4 = () => {
    let n = {
        a: 10,
        b: 20,
    };

    return n;
}

 

여기서 n 변수를 선언하지 않고 바로 return 뒤에 객체를 선언하여 반환시켜보자.

 

const f4 = () => {
    return {
        a: 10,
        b: 20,
    };
}

 

눈치가 빠른 사람들은 저 코드를 한 줄로 바꿔보려할 것이다. 그런데 여기서 문제가 발생한다. 한 줄로 처리할 때 return을 지우며 Scope까지 같이 지워야 한다. 그런데 객체를 생성할 때 이미 Scope가 있기 때문에 Lambda함수는 정상적으로 인식을 하지 못한다.

 

const f4 = () => { a: 10, b: 20, }; //에러 발생

 

이것을 해결하기 위해선 소괄호 ()를 객체 외부에 포개어주면 된다.

 

const f4 = () => ({ a: 10, b: 20, });

 

- 함수를 이용한 함수 호출

이번엔 함수를 이용해 함수를 호출하는 방법에 대해 작성하겠다.

함수 f1 내부에 함수 f2를 생성하고, return을 함수 f2를 설정하자.

 

const f1 = () => {
    console.log('function1 Call.');
    
    const f2 = () => {
        console.log('function2 Call.');
    }

    //만에하나, f2()를 리턴하면 함수 코드를 바로 리턴하는 형태.
    //지금은 f2에 대한 function을 리턴시키는거임. 
    return f2;
}
f1()();

 

주석과 같이 f2()가 아닌 f2를 return하기 때문에 function에 대한 정보만 반환할 뿐이지 함수를 Call 하는 것이 아니다. 이점을 주의 하자.

실제로 f2 함수를 호출하려면 소괄호를 두 번 써야한다. 그 이유는 f1()을 통해 함수 f1을 Call 한다. 이후 반환하는 f2를 Call 하기 위해 소괄호 ()를 붙여야 하기 때문이다.

 

이번에는 함수 내부에 함수를 생성하고 인자를 받는다 생각해보자.

 

const f1 = () => {
    const f2 = (n, s) => {
        console.log(n, s);
    }
    return f2;
}
f1()(10,'호랑이');

 

앞에서와 같이 f1()을 통해 함수1를 먼저 호출해주고, 이후 인자를 받는 소괄호를 작성하여 f2에 대한 function 코드를 Return 받고 Call 할 수 있도록 한다.