함수 선언식 & 함수 표현식
함수 선언식 : Function Declaration
호이스팅 처리(=선언문이 최상위에서 처리되는 것)되어 선언 전에 호출이 가능하다.
함수 표현식 : Function Expression
호이스팅 처리되지 않아 선언 전에 호출이 불가능하다.
익명 함수를 대입
<button onclick="test1();">함수 선언식</button>
<button onclick="test2();">함수 표현식</button>
test1();
function test1(){
console.log('함수 선언식!');
}
const test2 = function(){
console.log('함수 표현식!');
};
test1은 함수선언식으로, 함수가 선언되기 전에 test1();이 언급되었으나, 호이스팅 처리로 인해 선언 전에 사용이 가능하다.
test2는 변수대입을 함수로 선언한 것으로, 선언 전에 호출이 불가능하다.
즉시 실행 함수 (Immediately Invoked Function Expression)
iife (iify)
선언 호출 동시에 처리.
지역변수로 전환해서 안전하게 처리해야 할 때 사용.
( ( ) => { } ) ( ); --> 추천 방법. ( ) 안에 매개변수를 쓴다.
( ( () => { } ) ( ) );
(function(){
console.log('바로 실행!');
let cnt = 0;
console.log(cnt);
})();
(function(t){
console.log(t + ' 정말 바로 실행!');
}('완전'));
매개인자, 매개변수
매개인자(값) argument - 함수 호출부에 적는 것
매개변수(공간) parameter - 함수 선언부에 적는 것
자바스크립트 함수의 매개변수의 순서, 타입과 매개인자의 순서, 타입이 일치하지 않아도 오류가 발생하지 않는다.
<button onclick="test3();">매개인자 | 매개변수</button>
<button onclick="test4();">arguments</button>
const test3 = function(){
console.log(add(3, 5)); // 8
console.log(add(3)); // NaN
console.log(add(3, 5, 7)); // 8
console.log(add('hello', 'world')); // helloworld
};
const add = function(a, b){
console.log(`a = ${a}, b = ${b}`);
return a + b;
}
매개변수가 a,b 두개일때, 1개만 적으면 NaN, 3개를 적으면 앞의 두개만 적용된다.
타입이나 순서는 일치하지 않아도 매개인자에 쓴 순서대로 출력된다.
숨은참조 argument
숨은 참조인 arguments를 통해서 호출 시 전달된 모든 인자에 접근할 수 있다.
arguments는 모든 인자를 담은 유사배열이다.
화살표함수에서는 사용할 수 없다.
const test4 = function(){
console.log(addAll(1, 2, 3));
console.log(addAll(10, 20));
console.log(addAll('hello', 'world', 'byebye', 'world'));
};
const addAll = function(){
let sum = (typeof arguments[0] === 'number') ? 0 : ''; //0번지 체크
// console.log(arguments);
[...arguments].forEach(function(elem, index){
// console.log(elem, index);
sum += elem;
});
return sum;
};
리턴값 처리.
모든 함수는 암묵적으로 undefined를 리턴한다.
리턴값을 지정하면 그제서야 return값이 제대로 리턴된다.
const test5 = function(){
console.log(foo());
};
const foo = function(){
};
const test5 = function(){
console.log(foo());
};
const foo = function(){
return "fooooooooooooooooo";
};
나머지 파라미터 Rest Parameter (ES6)
모양은 전개연산자와 동일하지만, 사용위치가 다르다. (공간으로 사용)
매개변수 선언부에 사용.
전달된 인자를 하나의 배열에 모아서 처리.
마지막에 한번만 사용 가능.
전개연산자는 배열요소를 배치시킬 때 사용. (값으로 사용)
const test6 = function(){
info('홍길동', 33, '농구', '축구');
info('신사임당', 44, '뜨개질', '칼질', '물수제비');
info('세종대왕', 55);
};
const info = function(name, age, ...hobbies){
console.log(hobbies);
console.log(`이름 : ${name}
나이 : ${age}
취미 : ${hobbies}`);
const copy = [...hobbies];
};
매개변수부의 기본값처리 (ES6)
해당 자리에 매개인자가 전달되지 않았을 경우 기본값으로 처리됨.
const test7 = function(){
sayName('신사임당'); // 신사임당님, 반갑습니다.
sayName(); // 홍길동님, 반갑습니다.
};
const sayName = function(name = '홍길동'){
console.log(`${name}님, 반갑습니다.`);
};
사진 설명을 입력하세요.
화살표함수 Arrow Function (ES6)
익명 함수를 간단히 작성하는 문법
function( ) { } 를 완전히 대체하지는 않는다.
arguments 참조 변수 사용 불가
생성자 함수로 사용 불가
자신의 this가 없고, 부모스코프의 this를 가져와 binding.
- 매개변수가 하나인 경우, 소괄호 생략 가능
- 함수 몸통부가 한줄인 경우, { return } 생략 가능
- 실행부가 한줄인 경우, { } 생략가능
const test8 = () => {
f1(100);
console.log(f2(30, 50));
console.log(f3('홍길동', 33));
f4(200);
};
// 매개변수가 하나인 경우, 소괄호 생략가능
const f1 = a => {
console.log(a);
};
// 함수몸통부가 한줄인 경우, { return } 생략가능
const f2 = (a, b) => a + b;
const f3 = (_name, _age) => ({name : _name, age : _age}); // 객체를 반환하는 경우 소괄호 작성
// 실행부가 한줄인 경우, {} 생략가능
const f4 = a => console.log(a);
실습문제 - 계산기 만들기
const test9 = () => {
console.log(calc('add', 10, 20)); // 30
console.log(calc('add', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) // 55
console.log(calc('subtract', 100, 70)); // 30
console.log(calc('multiply', 11, 2, 5)); // 110
console.log(calc('multiply', 9, 5)); // 45
console.log(calc('divide', 100, 3)); // 33
};
const _calc = (type, ...nums) => {
return nums.reduce((arr, num) => {
switch(type){
case 'add': return arr + num;
case 'subtract': return arr - num;
case 'multiply': return arr * num;
case 'divide' : return Math.floor(arr / num);
}
});
};
const calc = (type, ...nums) => {
let result = nums[0];
switch(type){
case 'add':
for(let i = 1; i < nums.length; i++)
result += nums[i];
break;
case 'subtract':
for(let i = 1; i < nums.length; i++)
result -= nums[i];
break;
case 'multiply':
for(let i = 1; i < nums.length; i++)
result *= nums[i];
break;
case 'divide' :
for(let i = 1; i < nums.length; i++)
result = Math.floor(result / nums[i]);
break;
}
return result;
};
함수 고급
1. 함수를 매개인자로 사용 - 함수는 1급 객체. 함수를 값으로써 사용한다.
2. 함수를 리턴값으로 사용
- 함수를 매개인자로 사용.
const test10 = () => {
// 원시값을 변수에 대입
const x = 100;
const y = x;
console.log(x);
console.log(y);
// 함수를 변수에 대입
const a = () => console.log('안녕');
const b = a;
a();
b();
const f = (n) => console.log(`안녕${n}`);
runner(f); // 매개인자(값)
// runner(100); // Uncaught TypeError: f is not a function
};
const runner = (f) => {
console.log(typeof f, f); // function (n) => console.log(`안녕${n}`);
// typeof f === 'function' && f();
for(let i = 0; i < 10; i++)
f(i);
};
원시값을 변수에 대입 -> 함수를 변수에 대입 -> 함수의 매개인자를 가지는 값을 const로 선언하여 매개인자처럼 받기.
2. 함수를 리턴값으로 사용.
const test12 = () => {
// const result = m();
// console.log(typeof result, result);
// result('메롱');
const hello = funcMaker('안녕'); // word를 출력하는 함수
hello('철수');
const helpMe = funcMaker('돈 좀 꿔줘~');
helpMe('철수');
const bye = funcMaker('잘가');
bye('철수');
const friends = ['철수', '영희', '진구', '태양'];
friends.forEach((name, index) => helpMe(name));
// friends.forEach(helpMe); 똑같음!
};
const m = () => {
return (a) => console.log('안녕' + a);
};
const funcMaker = (word) => {
return (name) => {
console.log(`${name}야~ ${word}`);
};
};
const _funcMaker = (word) => ((name) => {
console.log(`${name}야~ ${word}`);
});
this용법 3, 4
3. 일반 함수 안에서 this는 window전역객체를 가리킨다.
4. 화살표함수는 this가 없다. 부모스코프의 this를 가져와 바인딩한다. 부모스코프는 화살표함수의 선언위치를 의미.
this가 바인딩 되면 변경할 수 없다.
function test14(){
console.log(this); // window
console.log(window); // window
}
const test15 = () => {
console.log(this); // window
};