개발 공부/자바스크립트

[엘리의 드림코딩 JS] 5. 함수(Function)

5묘 2022. 12. 4. 15:06

https://youtu.be/e_lU39U-5bQ

Function은 sub-program이라고도 불린다. 그만큼 function은 프로그램의 작동에 있어 중요하다!

//Function
// - fundamental building block in the program
// - subprogram can be used multiple times
// - performs a task or calculate 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();

function log(message) {
  console.log(message);
}
log('hello@');
log(4247);


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


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


// 4. Rest parameters (added in ES6)
function printAll(...args){
  // 방법1
  // for (let i=0; i< args.length; i++) {
  //   console.log(args[i]);
  // }

  //방법2
  // for (const arg of args) {
  //   console.log(arg);
  // }
  // cf) for...of는 배열의 반복, 
  // for...in은 객체의 반복에서 사용.
  // 배열에서 for ... in 쓰면 인덱스가 출력됨.(객체에서 키에 해당.)

  //방법3
  args.forEach((arg) => console.log(arg));

}
printAll('dream', 'coding', 'ellie')
//cf) rest parameter vs spread operator
// rest parameter은 function의 인자로서, 들어오는 복수의 인자들을 배열로 만들어주는 것.
// spread operator(또는 spread syntax)은 함수 호출 시에 array의 요소들을 펼쳐서 리스트의 인자들로 만들어주는 것.
let arr1 = [3, 5, 1];
console.log(Math.max(arr1)); // NaN

let arr2 = [3, 5, 1];
console.log( Math.max(...arr2) ); // 5 (spread turns array into a list of arguments)


// 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); // 바깥 스코프의 local variable => 안에서 사용 가능
    let childMessage = 'bye';// local variable => 바깥에서 호출 못함.
  }
  printAnother();
  // console.log(childMessage); //error
  // return undefined // return 값 명시 안해줄때 이게 생략된 상태임
}
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 ){
    // long upgrade logic ...
  }
}

//good
function upgradeUser(user) {
  if (user.point <= 10 ){
    return;  // 조건에 안맞으면 빨리 exit(dfs 알고리즘 때 해봤던 방법)
  }
  // long upgrade logic ...
}


// Firts-class function
// functions are treated like any other variable.
// can be assigned as a value to varialbe
// can be passed as an argument to other function
// 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 () {
  //anonymous function
  console.log('print');
}
print();
const printAgain = print;
printAgain();
const sumAgain = sum;
console.log(sumAgain(1, 3));


// 2. Callback function using function expression
// 함수를 함수의 인자로 전달해 실행시킴.
function randomQuiz(answer, printYes, printNo) {
  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 print() { 
  console.log('no!');
};
randomQuiz('wrong', printYes, printNo);
randomQuiz('love you', printYes, printNo);


// Arrow Function
// always anonymous
const simplePrint = function () {
  console.log('simplePrint!');
};

const simplePrint2 = () => console.log('simplePrint!');
const add = (a, b) => a + b; // block 있을 때만 return 씀.


// IIFE: Immediately Invoked Function Expression(즉시 호출 함수 표현식)
// 선언과 동시에 호출
(function hello(){
  console.log('IIFE');
})();


function calculate(command, a, b) {
  switch (command) {
    case 'add':
      return a + b;
    case 'substract':
      return a - b;
    case 'divide':
      return a / b;
    case 'multiply':
      return a * b;
    case 'remainder':
      return a % b;
    case 'exponentiation':
      return a ** b;    
    default:
      return NaN;
  }
}

console.log(calculate('exponentiation', 2, 3))