공부하는 동안 계속 이곳 저곳에서 등장하길래 튜터님께 물어봤다.
일단 지금 단계에서 제대로 이해하기엔 지나치게 어렵고 깊은 내용.
현재로서는
표현식은 반드시 value 로 나오기 때문에 변수에 담긴다. 그리고 변수에 담긴 함수는 그 함수 이름으로 호출할 수 없다.
const start = function startGame() {
console.log("Game is starting...");
};
startGameBtn.addEventListener("click", startGame); // 여기 start 를 적어야 호출
Q . 그렇다면 표현식으로 적을때 어차피 이름으로 호출 못하는거면 이름 적는게 의미가 없는거 아닌가?
A . 이름이 있어야 디버깅 할때 어디서 문제가 생겼는지 파악이 빠르다. 익명이면 anonymous function 이라고 떠서 난감하다.
물론 표현식으로 적을땐 진짜 이름을 안적어도 된다. 그게 익명 함수다.
const start = function () {
console.log("Game is starting...");
};
이렇게 이름 빼도 아무 문제 없다는것.
Q . 애초에 표현식이 왜 좋은건데?
A . 호이스팅 방식이 다르다. 선언식으로 함수를 적으면 함수가 통째로 호이스팅 되지만 표현식으로 함수를 적으면 식별자만 호이스팅 되고(?) 그 함수가 initialize 되지 않는다. 따라서 그 함수가 정의되기 전에 쓰려고 하면 오류 메시지를 출력한다. 글로 적으니 이상해지는데 예시를 보자.
start();
const start = function () {
console.log("Game is starting...");
}; // Cannot access 'start' before initialization
함수를 정의 하기 전에 쓰려고 했기 때문에 위처럼 오류메시지가 나온다.
그리고 이렇게 함수가 사용되기 전에 정의 하도록 강제하는 것은 읽기 쉬운 코드를 만든다.
익명 함수를 꼭 변수에 할당해야 하는건 아니다
startGameBtn.addEventListener("click", function () {
console.log("Game is starting...");
});
이런 식으로 사용할 곳에서 바로 만들어서 써도 됨.
위와 같은 익명 함수 활용은 보통 그 함수를 처음이자 마지막으로 사용할 때 씀.
이런 식으로 적었을때 장점은 그 함수가 뭘 참조하고 있는지 찾아볼 필요도 없이 그냥 저 버튼을 누르면 무슨 일이 일어날지가 바로 파악된다는 점.
익명 함수에서 function 글자 빼고 () 와 {} 사이에 => 넣으면 그게 그냥 화살표 함수.
중괄호 안에 표현식이 하나만 있다면 중괄호와 return도 생략할 수 있다.
const add = (a,b)=>a+b;
이렇게 아주 간략하게 함수를 쓸 수 있다.
또한 인자가 하나라면 ( ) 도 생략할 수 있음.
스프레드 연산자랑 똑같이 생겼다 ( ... )
함수에서 인자를 몇 개 받을지 미리 알수 없을때 사용한다.
const sumUp = (...numbers) => {
let sum = 0;
for (const num of numbers) {
sum += num;
}
return sum;
};
console.log(sumUp(1, 5, 10, -3, 6, 10)); //29
console.log(sumUp(1, 5, 10, -3, 6, 10, 25, 3)); //57
몇개가 될지 모르는 수들을 인자로 받아서 죄다 더하는 함수를 만들때 rest 연산자를 사용한 예시이다.
rest 연산자는 몇개의 인자를 받든 그걸 모조리 모아다 array로 만들어 버린다. 따라서 함수는 인자로 배열을 받는 상황이 되고 그래서 for-of 구문을 사용한 것이다.
rest 연산자를 쓸때 rest 연산자는 항상 마지막 인자여야 한다. 그래서 당연히 rest연산자는 한번만 쓸 수 있다
(두번 쓰면 처음 쓴 rest 연산자가 마지막 인자가 아니게 되잖아)
(a,b, ...numbers) 이렇게 써있으면 어떻게 될까?
첫번째와 두번째 인자는 각각 a, b 로 할당이 되고 그 이후 전달된 인자들은 numbers로 이름붙는 배열에 묶인다.
(예문에서는 배열 안에 있는 수만 처리하므로 a,b는 계산에서 제외된다)
자매품 : arguments
function 이라는 단어가 쓰인 함수에서만 쓸수 있다(화살표 함수에선 안된단 소리)
const subtractUp = function () {
let sum = 0;
for (const num of arguments) {
sum -= num;
}
return sum;
};
console.log(subtractUp(1, 10, 15, 20)); // -46
es6에서 rest연산자가 도입되기 전까지 rest 연산자의 역할을 했다는데 지금은 rest 연산자를 쓰는게 더 바람직하다. 쓰지 말자!
함수의 인자를 '사전구성' 하려는 상황에서 함수를 직접 호출하지 않을 때 유용하게 사용된다.
그 함수가 받을 인자들을 미리 세팅해둘 수 있다.
this 를 bind 하는 것은 아직 잘 모르겠다. 알게되면 Follow up에 적을것!
call, apply 도 매개변수를 지정할 수 있지만 bind와 다르게 바로 호출된다.
var count = 0;
var cbFunc = () => {
console.log(count);
if (++count > 4) clearInterval(timer);
};
var timer = setInterval(cbFunc, 300);
//실행시키면 0.3 초 간격으로 0 1 2 3 4 가 찍힘.