본문 바로가기
JavaScript

[JavaScript] 함수의 선언과 표현

by happenstance 2021. 8. 5.

함수의 선언식과 표현식의 차이점 / Arrow function에 대해서 알아보기

// Function
// - fundamental building block in the program
// - subprogram can be used multiple times
// - performs a task or calculates a value

// 1. Function declaration
// function name(param1, param2) { body...return; }
// ⭐ one function === one thing (하나의 함수는 한 가지의 일만 하도록 생성해야 함)
// naming: doSomething, command, verb
// e.g. createCardAndPoint -> createCard, createPoint
// function is object in JS
// => 자바스크립트에서 function은 object이기 때문에
//    변수 할당, 파라미터 전달, 함수 리턴 가능
function printHello() {
    console.log('Hello');
}
printHello();

function log(message) {
    console.log(message);
}
log('Hello!');

// 2. Parameters
// primitive parameters: passed by value
// object parameters: passed by reference
function changeName(obj) {
    obj.name = 'coder';
}
const kim = { name: 'kim' };
changeName(kim);
console.log(kim); // {name: "coder"}

// 3. Default parameters (added in ES6)
// 1) 예전 방식
function showMessage(message, from) {
    if (from === undefined) {
        from = 'unknown';
    }
    console.log(`${message} by ${from}`);
}
showMessage('Hi!'); // Hi! by unknown

// 2) 최근 방식
function showMessage(message, from = 'unknown') {
    console.log(`${message} by ${from}`);
}
showMessage('Hi!'); // Hi! by unknown

// 4. Rest parameters (added in ES6)
function printAll(...args) { // 배열 형태로 전달 됨
    for (let i = 0; i < args.length; i++) {
        console.log(args[i]);
    }

    for (const arg of args) {
        console.log(arg);
    }

    args.forEach((arg) => console.log(arg));
}
printAll('dream', 'coding', 'kim');

// 5. Local scope
let globalMessage = 'global'; // global variable
function printMessage() {
    let message = 'hello';
    console.log(message); // local variable
    console.log(globalMessage);
    function printAnother() {
        console.log(message);
        let childMessage = 'hello';
    }
    // console.log(childMessage); // error => 지역 변수이기 때문에 부모가 사용할 수 없음
    return undefined; // 생략 가능
}
printMessage();

// 6. Return a value
function sum(a, b) {
    return a + b;
}
const result = sum(1, 2); // 3
console.log(`sum: ${sum(1, 2)}`);

// 7. Early return, early exit
// bad
function upgradeUser(user) {
    if (user.point > 10) {
        // lang upgrade logic...
    }
}

// good
function upgradeUser(user) {
    if (user.point <= 10) {
        return;
    }
    // lang upgrade logic...
}


// First-class function
// functions are treated like any other variable
// can be assigned as a value to variable
// can be passed as an argument to other functions.
// can be returned by another function

// 1. Function expression
// a function declaration can be called earlier than it is defined. (hoisted)
// a function expression is created when the execution reaches it.
const print = function () { // 함수를 선언함과 동시에 print라는 변수에 할당함 => anonymous function (익명 함수)
    console.log('print');
};
print();
const printAgain = print;
printAgain();
const sumAgain = sum; // 위에서 만든 sum 함수를 사용함
console.log(sumAgain(1, 3));

// 2. Callback function using function expression
function randomQuiz(answer, printYes, printNo) { // printYes, printNo라는 두 개의 Callback function을 매개변수로 받음
    if (answer === 'love you') {
        printYes();
    } else {
        printNo();
    }
}
// anonymous function -> 함수의 이름이 없음
const printYes = function () {
    console.log('yes!');
};
// named function
// better debugging in debugger's stack traces
// recursions
const printNo = function () {
    console.log('no!');
};
randomQuiz('wrong', printYes, printNo); // no!
randomQuiz('love you', printYes, printNo); // yes!

// Arrow function
// always anonymous
// 1) Arrow function 쓰기 전
// const simplePrint = function () {
//     console.log('simplePrint');
// };
// // 출력
// const add = function (a, b) {
//     return a + b;
// };
// 2) Arrow function 쓰기 후
const simplePrint = () => console.log('simplePrint');
// 출력
const add = (a, b) => a + b;
// 괄호가 필요하다면 아래와 같게도 가능함
const simpleMultiply = (a, b) => {
    // do something more
    return a * b; // return 필수
};

// IIFE : Immediately Invoked Function Expression
// 함수를 선언함과 동시에 바로 호출하기
(function hello() {
    console.log('IIFE');
})();

// Quiz
// function calculate(command, a, b)
// command: plus, subtract, divide, multiply, remainder
function calculate(command, a, b) {
    switch (command) {
        case 'plus': return a + b;
            break;
        case 'subtract': return a - b;
            break;
        case 'multiply': return a * b;
            break;
        case 'divide': return a / b;
            break;
        case 'remainder': return a % b;
            break;
        default:
            throw Error('unknown command');
    }
}
console.log(calculate('plus', 2, 3));