
함수란, 특정 작업을 수행하도록 정의해둔 로직을 의미한다. 함수를 정의해 두면 필요에 따라 호출하여 사용할 수 있으며, 인자를 전달받는 것도 가능하다.
함수는 기본적으로 Input 받기, 기능(함수) 수행, Output 반환이 있다.
아래 4가지 경우 모든 요소가 없어도 모두 함수로서 작용이 가능하다.
함수 선언 방식은 3가지로 분류된다. 함수 선언식(function declaration 명시적 함수), 함수 표현식(function expression 익명 함수), function 생성자를 이용한 방법이 있다.
⚙️ function 생성자를 이용하는 방법은 거의 사용되지 않으니 나머지 2가지 방법을 알아보자.
// 함수 선언식 (Function Statements)
// 반드시 함수 이름이 명시되어야 하며, 함수 이름으로 함수를 호출한다.
function a() {
    console.log('Hello World')
}
a()
// 함수 표현식 (Function Expressions)
// 함수 리터럴로 생성한 함수를 변수에 할당하는 방법을 함수 표현식이라고 한다. 함수의 참조값이 'a'라는 변수로 저장된다.
// 
var a = function() {
    console.log('Hello World 2')
}
a()
호이스팅(hoisting): 자바스크립트 엔진이 script 태그를 만나면 자바스크립트 파일을 먼저 쭉 읽으면서 선언된 변수와 함수를 메모리에 저장한다. 
아래 코드를 예로 들면 먼저 변수 name과 sayName 함수(전체), sayHello 변수가 메모리에 저장되는 것이다. 이 과정이 끝나면 코드가 위에서 부터 차례대로 실행되는데 sayName() 함수의 경우 메모리에 저장되어 있기 때문에 문제없이 실행되지만 sayHello의 경우 아직 값이 할당되기 전이기 때문에 에러가 발생한다.
sayName(); // 'dongwhee'
sayHello() ; // 그런 함수 존재하지 않음
var name ='dongwhee';
function sayName(){ console.log('dongwhee') }
var sayHello = function(){ console.log('hello') };
// bad
function foo() {
  // ...
}
// bad
const foo = function () {
  // ...
};
// good
// lexical name distinguished from the variable-referenced invocation(s)
const short = function longUniqueMoreDescriptiveLexicalFoo() {
  // ...
};
예시 참조 : Google JavaScript 스타일 가이드
function a(){
    let str = "return 값이 있는 함수가 실행되었습니다.";
    return str;
}
console.log(a());
function score() {
  let myScore = 5;
  return myScore;
}
let myScoreMultiple = myScore * 2;
console.log(myScoreMultiple) // 10
function multiply(a, b) {
  return a * b
}
multiply(5, 2)  // 10
multiply(5)     // NaN !
function multiply(a, b = 1) {
  return a*b
}
multiply(5, 2)          // 10
multiply(5)             // 5
multiply(5, undefined)  // 5
// 일반 함수
let hi = function () { console.log("hi") }; // hi
// 화살표 함수
let hey = () => console.log("hey"); // hey