[JS] 함수(Functions)

2020. 6. 3. 20:00프론트엔드/JAVASCRIPT

728x90

1. Function

-fundamental building block in the program

-subprogram can be used multiple times

-perfirns a task or calculates a value

 

1-1. Function declaration

function name(param1, param2) {body... return;}

one function === one thing(한 개의 함수는 한 가지의 일만 하도록 작성해야함)

e.g. createCardAndPoint -> createCard, createPoint

function is object in JS (자바스크립트에서 함수는 Object로 간주)

변수에 할당할 수도 있고 파라미터로 전달되고 함수를 리턴도 가능

function printHello() {
  console.log("Hello");
}
printHello(); //Hello

function log(message) {
  console.log(message);
}
log("Hello@"); //Hello@

 

자바스크립트에서는 타입이 없기 때문에

log라는 함수의 인터페이스만 보면(log함수가 정의된 정의내용만 파라미터만 보면 )

파라미터로 string이 전달되는건지 number가 전달되는건지 명확하지 않음

자바스크립트에서 log(1234) 호출하면 파라미터가 number형이지만 string형으로 변환되어 출력은 되겠지만

타입이 중요한 함수라면 자바스크립트는 난해할 있음

반면에 타입스크립트를 사용한다면 타입스크립트는 타입이 정의하기 때문에 아주 명확함

 

1-2. Parameters

premitive parameters: passed by value

(premitive type은 메모리에 value가 그대로 저장되기 때문에 parameter로 value가 그대로 전달됨)

object parameters: passed by reference

(object는 메모리에 reference가 저장되기 때문에 parameter로 object를 가리키는 reference가 전달됨)

function changName(obj) {
  obj.name = "coder";
}
const ellie = { name: "ellie" };
changName(ellie); // ellie의 name을 'coder'로 변경
console.log(ellie); //{name: "coder"}

 

1-3. Default parameters(added in ES6)

// 두 개의 파라미터를 받는 'showMessage'라는 함수를 선언
function showMessage(message, from) {
  console.log(`${message} by ${from}`);
}

//'showMessage'를 호출할 때 파라미터를 한 개만 전달
showMessage("showMessage"); //showMessage by undefined
//예전에는 이럴경우를 대비해 파라미터가  undefined일 경우 아래처럼 조건문을 통해 값을 정의
function beforeShowMessage(message, from) {
  if (from === undefined) {
    from = "unknown";
  }
  console.log(`${message} by ${from}`);
}
beforeShowMessage("beforeShowMessage"); //beforeShowMessage by unknown

// 하지만 지금은 (ES6부터는) undefined일 경우를 대비해서 전달받을 파라미터 옆에 기본값을 정의
function afterShowMessage(message, from = "unknown") {
  console.log(`${message} by ${from}`);
}
afterShowMessage("afterShowMessage"); //afterShowMessage by unknown

 

1-4. Rest parameters(added in ES6)

여러개의 파라미터를 전달시 배열형태로 파라미터가 전달됨

function printAll(...args) {
  for (let i = 0; i < args.length; i++) {
    console.log(args[i]);
  }
  //위의 for Loop를 조금 더 간단하게 출력
  for (const j of args) {
    console.log(j);
  }
  //위의 for Loop를 조금 더 간단하게 출력
  args.forEach(j => console.log(j));
}
printAll("dream", "coding", "ellie");
//dream
//coding
//ellie

 

1-5. Local scope

let globalMessage1 = "global1"; //global variable
function printMessage() {
  let localMessage1 = "local1";
  console.log(localMessage1); //local varible
  console.log(globalMessage1);
}
printMessage();
//console.log(localMessage1); //error발생
//local varible를 선언된 함수 바깥에서 출력했기 때문에 error발생
//global1
//local1
let globalMessage2 = "global2"; //global variable
function printMessage2() {
  let localMessage2 = "local";
  console.log(localMessage2); //local varible
  console.log(globalMessage2);
  function innerprintMessage2() {
    console.log(localMessage2);
    let childLocalMessage2 = "childLocal";
  }
  //console.log(childLocalMessage2);  //error발생
  //childLocalMessage2는 innerPrintMessage2에 정의되어 있기 때문에 innerPrintMessage2함수의 바깥에서 출력하려 하면 에러발생
}
printMessage2();

-자바스크립트에서 스코프란안에 정의된 변수를 바깥에서는 접근이 불가능하고 바깥에서 선언된 변수는 안에서 접근이 가능

-자바스크립트에서 printMessage2와 같이 중첩된 함수에서 자식의 함수가 부모의 함수에서 정의된 변수에 접근이 가능한 '클로저'라고

 

 

1-6. Return a value

return type이 없는 함수들은 'undefined' return하는 것과 똑같음(return undefined) -> 생략

그러니까 모든 함수는 return undefined이거나 return 값을 지정해서 리턴

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

 

 

1-7. Early return, early exit

// bad function  : 조건을 만족하는 경우에 먼저 if문에서 긴 로직을 처리
function upgradeUser(user) {
  if (user.point > 10) {
    //long upgrade logic ...
  }
}
//good function : 조건을 만족하지 않는 경우에 먼저 if문에서 return;으로 처리하고 조건을 만족하면 실행하는 로직은 그 뒤에 처리
function upgradeUser(user) {
  if (user.point <= 10) {
    return;
  }
  // long upgrade logic ...
}

 

 

 

2. 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 othher functions

can be retunrned by another function

 

2-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() {
  //annoymous function(이름이 없는 함수) <-> named function(이름이 있는 함수)
  console.log(`print`);
};
print();
const printAgain = print;
printAgain();
const sumAgain = sum;
console.log(sumAgain(1, 3));

- a function expression은 위와 같이 할당된 다음부터 호출이 가능(변수에 할당 전에 호출시 당연히 에러발생)

 - a function declaration는 호이스팅이 되기 때문에 함수가 선언되기 이전에 호출하는 것이 가능(호출 전에 선언된 함수를 위로 끌어올려놓기 때문에 가능:hoist)

 

 

 2-2. Callback function using function expression

function randomQuiz(answer, printYes, printNo) {
  if (answer === "love you") {
    printYes();
  } else {
    printNo();
  }
}
// annoymous function
const printYes = function() {
  console.log("yes!");
};
// named function
// better debugging in debugger's stack traces (디버깅을 할 때 (stack traces에) 함수이름이 나오게 하려고 주로 named function 사용)
// recursions(함수 안에서 함수 자신 스스로를 부르는 것 : 함수 안에서 또 다른 함수를 호출할 경우 주로 named function 사용)
const printNo = function print() {
  console.log("no!");
};
randomQuiz("wrong", printYes, printNo);
randomQuiz("love you", printYes, printNo);

 

 

2-3. Arrow function

- always annoymous ( Arrow function은 항상 annoymous function)

- 훨씬 간결하게 표현 가능

// 훨씬 간결하게 표현 가능
const simplePrint = function() {
  console.log("simplePrint!");
};
const arrowSimplePrint = () => console.log("arrowSimplePrint!"); //위의 simplePrint 함수를 arrow함수로 표현

const add = function(a, b) {
  return a + b;
};
const arrowAdd = (a, b) => a + b; //위의 add 함수를 arrow함수로 표현
// 함수가 한 줄일 경우에는 블럭('{}')없이 표현이 가능하지만 함수 내용이 길어진다면 아래와 같이 표현하는데
// 블럭사용시에는 'return'키워드 사용해서 리턴해야함
const simpleMultiply = (a, b) => {
  //do something more
  return a * b;
};

 

 

2-4. IIFE: Immediately Invoked Function Expression

-일반적으로 함수를 선언했으면 따로 함수를 호출해야만 함수를 실행시킬 있는데 IIFE는 선언함과 동시에 실행가능

(function hello() {
  console.log("IIFE");
})();

 

 

 

 

*QUIZ

// function calculate(command, a, b)
// command add, subtract, divide, multiply, reminder
function calculate(command, num1, num2) {
  console.log(num1);
  if (
    (num1 !== null || num1 !== undefined) &&
    (num2 != null || num2 != undefined)
  ) {
    num1 = Number(num1);
    num2 = Number(num2);
    switch (command) {
      case "add":
        return num1 + num2;
        break;
      case "subtract":
        return num1 - num2;
        break;
      case "divide":
        return num1 === 0 ? "0으로 나눌 수 없습니다" : num1 / num2; // 0/1 불가눙하므로 삼항연산자로 한 번 더 처리
        break;
      case "multiply":
        return num1 * num2;
        break;
      case "reminder":
        return num1 / num2;
        break;
      default:
        return "잘못된 입력값입니다.";
    }
  } else {
    return "계산할 값을 정확히 입력해주세요.";
  }
}
calculate("add", "1", "2");

 

참고 : 드림코딩 by 엘리 유튜브

728x90

'프론트엔드 > JAVASCRIPT' 카테고리의 다른 글

[JS] javascript:void(0) 과 #  (0) 2020.06.08
[JS] 클래스(Class)  (0) 2020.06.04
[JS] 반복문(Loops)  (0) 2020.05.31
[JS] 연산자(Operator)  (0) 2020.05.31
[JS] 데이터 타입(Data Type)  (0) 2020.05.26