js function
A A

// 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 printHello() {
    console.log('Hello');
}
printHello();
/* Hello만 출력할 수 있으므로 활용도가 낮음 */

function log(message) {
    console.log(message);
}
log('Hello@');
log('this is my test');
log(1234);
// log함수를 호출하면서 원하는 메시지는 뭐든 출력할 수 있음

 

2. Parameters

/* premitive parameters: passed by value
object parameters: passed by reference */
function changeName(obj) {
    obj.name='coder';
}
const ellie={name: 'ellie'}; /*ellie라는 오브젝트를 만들어서 할당해주면 레퍼런스가 메모리에 들어가게 되고, 레퍼런스는 이 오브젝트를 메모리 어딘가에 가리킴(?) */
changeName(ellie); /* changeName 엘리를 전달하게 되면, obj.name에 따라 엘리를 coder로 변경하게 됨 */
console.log(ellie); /* 그래서 이렇게 콘솔로그로 출력할 때 coder로 변경되어 나옴 */

 

3. Default parameters (added in ES6)

function showMessage(message, from) {
    console.log(`${message} by ${from}`);
}
showMessage('Hi!'); /* 여기까지 쓰면 message는 출력이 잘 되지만, from이 정의되어 있지 않으므로 'undefined'라고 뜸 */

/* 그래서 if절을 넣어서 unknown으로 출력되도록 함 */
function showMessage(message, from) {
    if (from === undefined) {
        from = 'unknown';
    }
    console.log(`${message} by ${from}`);
}
showMessage('Hi!'); 
/* 라고 기껏 필기했더니 '굳이 귀찮게 이렇게 할 필요 없다'라고 하심 */

/* 그래서 나온 것 */
function showMessage(message, from = 'unknown') {
    console.log(`${message} by ${from}`);
}
showMessage('Hi!'); 
/* parameter 옆에 원하는 디폴트값을 지정해놓으면, 사용자가 parameter를 전달하지 않을 때 이 값으로 대체되어 출력됨 */

 

4. Rest parameters (added in ES6)

function printAll(...args) /* 이렇게 닷닷닷(...)을 놓으면 레스트파라미터라고 불리는데, 이것은 배열형태로 전달됨 (이런 게 있다-정도로) */
{
    for (let i=0; i<args.length; i++) {
        console.log(args[i]);
    }

    /* 간단하게 for - of를 이용해서 출력할 수도 있음 */
    for (const arg of args) {
        console.log(arg);
    }

    /* 더 간단하게 하고 싶다면(나중에 다시 배울 것) */
    args.forEach((arg) => console.log(arg));
}
printAll('dream', 'coding', 'ellie');

 

5. Local scope

let globalMessage='global'; /* global variable */
function printMessage() {
    let message='hello';
    console.log(message); /* local variable */
    console.log(globalMessage);
}
printMessage();
/* '밖에서는 안이 보이지 않고 안에서만 밖을 볼 수 있다'
블럭 안에서 변수를 선언하면 이것은 '지역 변수'임. 안에서만 접근이 가능하고, 이 메시지를 밖에서 출력하면 에러가 발생함.
하지만, 안에서는 이 globalMessage라는 것을 볼 수 있고 출력이 가능한 것을 확인할 수 있음. 이게 바로 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'; /* 이 자식은 부모에게서 정의된 메시지들을 확인할 수 있음. 하지만 자식 안에 정의된 차일드메시지를 부모(상위)에서 보려고 하면, 에러가 발생함. */
    }
}
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 ex.
function upgradeUser(user) {
    if (user.point>10) /* (유저 포인트가 10 넘을 때 ~한다) */
    {
        /* long upgrade logic... */
        /* 가독성이 떨어진다 */
    }
}
// good ex.
function upgradeUser(user) {
    if (user.point<=10) /* (조건이 맞지 않을 때에만,) */
    {
        return; /* (리턴하여 함수를 종료한다) */
    }
    /* long 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 functino expression is created when the execution reaches it. */
const print=function() { /* function함수를 선언함과 동시에 바로 print라는 변수에 할당하는 것 확인 가능. function에 아무런 이름이 없고(), function이라는 키워드를 통해 parameter와 block을 이용함. 이렇게 이름 없는 함수를 anonymous function이라 함. */
    console.log('print');
};
print();
const printAgain=print; /* 다시 다른 변수에 또 할당하게 되면, 결국 이 printAgain은 함수를 가리키고 있기 떄문에... */
printAgain(); /* print가 출력되는 것을 볼 수 있음. */
const sumAgain=sum; /* sum이라는 functions을 윗부분 어딘가에서 정한 적이 있는데ㅎ 이를 sumAgain에 할당하게 되면, */
console.log(sumAgain(1,3)); /* 이렇게 동일하게 호출할 수 있음. */

 

2. Callback functino using function expression

function randomQuiz(answer, printYes, printNo) {
    if (answer === 'love you') {
        printYes();
    } else {
        printNo();
    }
}
const printYes=function() { /* 이름 없는 anonymous function */
    console.log('yes!');
};
const printNo=function print() { /* 이름 있는 named function */
    console.log('no!');
};
randomQuiz('wrong', printYes, printNo);
randomQuiz('love you', printYes, printNo);
/* Arrow function
always anonymous */
const simplePrint=function() {
    console.log('simplePrint!');
};

/*
const simplePrint=() => console.log('simplePrint!');
// function 키워드, block 필요없음. 한 줄에 묶어 arrow(=>)로 표기하면 끝!
*/
const add=(a,b)=>a+b;
/* 이것을 풀어 쓰면 다음과 같음
const add=function(a,b) {
    return a+b;
}
*/
const simpleMultiply=(a,b)=>{
    /* do something more */
    return a*b;
};
/* IIFE: Immediately Invoked Function Expression */
/* 
function hello() {
    console.log('IIFE');
}
라는 함수를 호출하고 싶을 때, 이들을 ()로 묶고 바로 ();로 호출해주면 됨. 아래처럼 */

(function hello() {
    console.log('IIFE');
})();
// expected output: IIFE

 

Copyright 2024. GRAVITY all rights reserved