🦆 그룹 스터디 팀 러버덕과 함께!
<다룰 내용>
1.함수란?
2.함수사용이유
3.함수리터럴
4.함수 정의
5.함수 선언문
6.함수 표현식
7.함수 호이스팅
8.마무리
프로그래밍에서 함수는 입력값을 받으면 출력값을 반환한다.
입력값을 받으면 함수는 함수 내의 로직을 수행하여 결과물(출력값)을 반환한다.
예를 들면, 어떤 요리든 해주는 함수가 있다하면 입력값으로 떡을 넣으면
함수가 떡을 받아서 특정로직을 수행하여 결과물로 떡국을 주는것이다.
자바스크립트에서는 입력값을 '인수(argument)'라하고 출력값을 '반환값(return value)'이라한다.

1.재사용할 수 있다.
2.실행로직을 하나의 블록으로 묶음으로써 외부로부터 데이터를 숨길 수 있다.(스코프 개념)
함수도 객체다.
객체도 리터럴로 생성가능한것처럼
const a = {.....}
함수도 리터럴로 함수를 만들 수 있다.
함수리터럴로 함수 정의하기
function (){......}
함수 리터럴은 function (매개변수){ 함수 몸체 } 로 이루어진다.
함수리터럴은 이름이 없다(익명 함수).
함수를 정의하는 방법에는 4가지 방법이 있다.
1.함수 선언문으로 정의
function add(x, y) {return x + y;}
2.함수 표현식으로 정의
const add = function (x, y) {return x + y;}
3.Function 생성자로 정의
const a = new Function(’x’, ‘y’, ‘return x + y’)
4.화살표함수로 정의
const add = (x, y) ⇒ x + y;
함수선언문은 function키워드 + 이름 + 함수리터럴로 만들어진다.
함수선언문은 변수에 할당할수없지만 자바스크립트에서는 변수에 할당할 수 있다.
function sayHi() {
console.log("Hi!");
}
sayHi() // Hi!
하지만 ()그룹연산자로 함수선언문을 감싸게 되면 함수리터럴로 된다.
(function greet() { console.log("Hello"); })
greet() // ReferenceError: greet is not defined
함수선언문(sayHi함수)과 함수리터럴(greet 함수)은 호출하는 방식이 다르다.
sayHi함수는 외부호출이가능하지만 greet함수는 외부에서 호출할수없다.
함수 리터럴(greet함수)은 자바스크립트엔진이 단순 덧셈,뺄셈과 같은 계산하는 연산자로 인식하기때문에 greet함수객체가 메모리에 할당되면 이 메모리를 가리킬 식별자(이름)이 없다.따라서 외부에서 이 함수의 존재를 알 수 없으므로 ReferenceError가 발생하게된다.()그룹연산자를 실행할려면 바로 ()를 붙여주면된다. 하지만 함수의 정의와 동시에 즉시 실행되는데 이는 한번만 호출되며, 다시 호출할 수 없다. 이런 함수를 즉시 실행함수 IIFE (immediately invoked function expression)라 부른다.
(function greet() { console.log("Hello"); })()

반면 함수 선언문은 sayHi()를 호출하지않으면 실행되지않는다.
그리고 함수리터럴과 달리 외부에서 호출가능한 이유는 메모리에 sayHi함수객체가 할당되면 이 메모리를 참조할 식별자가 생긴다.
따라서 식별자로 함수 외부에서도 함수의 존재여부를 확인할 수 있다.

자바스크립트 함수는 일급객체이므로 변수에 함수객체를 할당할 수 있다.
하지만 함수의 이름은 생략하는 것이 일반적이다.
함수 표현식은 함수 리터럴을 변수에 할당하여 사용한다.
메모리 참조값의 식별자 이름은 변수(add)가 저장된다.
const add = function(x, y) {
return x + y;
}
add(2,5)
호이스팅이란 컴파일단계(코드실행전)에서 메모리에 모든 선언문(변수,함수,클래스)들을 할당하는것을 말한다.그래서 선언하기전에 변수등을 참조할수있다. 이 과정이 마치 선언문들이 코드 최상위로 끌어옮겨지는 '현상'같다해서 호이스팅('끌어올리다' )이라는 단어를 사용한 이유다.
함수 선언문은 함수 정의 전에 호출할 수 있지만,
함수 표현식은 함수 정의 전에 호출할 수 없다.
console.log(add(2,5)) // 7
function add(x,y) { return x + y; }
함수선언문은 호이스팅으로 코드 실행 전, 자바스크립트 엔진이 함수객체를 힙 메모리에 할당되므로 함수가 정의되기전에 함수를 호출 할 수 있다.

정리하자면,
console.log(add(2,5)) // TypeError: add is not a function
var add = function(x, y) {return x + y;}
함수표현식은 변수에 함수를 할당하는것이므로,
변수는 선언문만 메모리에 할당이되므로
즉,
let a=2;
1️⃣ let a; -> 선언문
2️⃣ a=2; ->대입문
이건 변수 호이스팅다룰때 다룰거지만 간단히 말하자면)
var는 선언과 동시에 초기화로 undefined값이 할당되고
let,const는 선언만되고 초기화는 되지않는다.

따라서, 함수표현식은
a() // ⛔️ ReferenceError
let a = function(){...}
a() // ⛔️ TypeError
var a = function(){...}
변수a 선언부분만 메모리에 할당되고 function(){...}대입문은 코드 실행될때 처리되므로 함수전에 let,const변수는 초기화가 되지않아서 ReferenceError가 나고
var은 디폴트 값으로 undefined이므로, undfined를 호출하는게 되니까 TypeError가 된다.
반면, 함수 선언문은 함수선언과동시에 힙 메모리에 할당된다.
이번 그룹스터디 러버덕과 함수를 공부하면서 단순히 '함수는 함수이름으로 호출하는것' 이렇게만 알고있었는데 함수이름이 아니라 함수 객체를 가리키는 식별자로 호출된다라는 사실을 알게되었다.
뿐만 아니라 호이스팅은 '단순히 맨위로 끌어다 올려주는것'으로 알고있었는데
런타임전에 모든 선언문을 메모리에 할당하는 것으로 먼저 메모리에 할당하고 난 뒤, 코드를 수행하는 것이다. 그래서 변수나 함수선언문은 정의되기전에 먼저 호출 할 수 있는것을 말한다.