function은 프로그램을 구성하는 중요한 블럭이다.
함수는 parameter로 값을 받아서 동작을 한 후 output을 내보낸다.
함수의 이름을 통해 해당 함수가 어떤 일을하고, 전달하는 파라미터를 통해 어떤 값을 리턴하는 지 예상할 수 있다.
그렇기 때문에 함수는 input, output, functionName이 굉장히 중요하다.
- 함수는 여러번 재사용이 가능하다.
- 그리고 대체적으로 한 가지의 task나 어떤 값을 계산하기 위해서 쓰여진다.
자바스크립트에서 함수를 정의하는 방법에는 함수의 선언과 함수의 표현이 있다.
function 함수이름(param1, param2,...) { 작업... return 결과; }
- 함수는 1가지의 일만 할 수 있도록 만들어야 된다.
- 함수의 이름을 작성할 때는 동사형태로 이름을 지정해야된다.
--> ~~한다. 의미가 담긴 값으로!- 자바스크립트에서의 함수는 Object이다.
그렇기 때문에 이 함수를 변수에 할당, 파라미터에 전달, 함수를 리턴할 수도 있는 것이다.
똑같은 작업밖에 못하는 함수
function printHello() { console.log('Hello JavaScript!!!'); }
파라미터로 들어오는 값을 받아서 여러작업을 할 수 있는 함수
function printAnything(value) { console.log(value); } printAnything('Hi!!!'); printAnything('I lova JavaScript!'); printAnything('Nice!'); // Number의 경우 숫자가 문자열로 변환되어서 문제가 발생하지 않는다. printAnything(12345678);
자바스크립트에는 타입이 없기 때문에 함수의 interface를 봤을 때는 위의 함수가 무슨 작업을 하는 지 모른다.
TypeScript
TypeScript에 대해서 아주 조금만 알아보았다.
아래의 printMessage함수는 파라미터의 값이 string만 들어올 수 있고,
리턴되는 값은 number로 리턴된다고 타입을 정해주고 있는 것이다.function printMessage(message: string): number { console.log(message); return 0; }
함수에 전달되는 파라미터들은
primitive type의 경우 메모리에 값이 그대로 전달되어 있기 때문에 값이 그대로 전달되고,
reference type의 경우 메모리에 주소가 저장되어있기 때문에 주소가 전달된다.아래의 함수는 파라미터로 전달받은 객체에서 name의 값을 무조건 'jy'로 변경하는 함수이다.
"use strict" let obj = { name: 'chip', age: 5, height: '17cm', weight: '300g', favorite: 'dotori', }; function changeName(obj) { obj.name = 'jy'; return obj; } let myName = changeName(obj); console.log(`변경된 사용자 아이디 : ${myName.name}`);
myName이라는 변수에 changeName함수를 실행한 결과의 값을 할당해주면, 함수의 결과값을 봤을 때 객체가 리턴되니까
변수에는 객체의 주솟값이 담겨있다.
function printName(name, age) { console.log(`${name}님의 나이는 ${age}살입니다! :)`); } printName('dotori');
printName 함수에는 매개변수로 2개의 값이 들어가야되는데
함수를 호출할 때 값을 1개만 넣어주었기 때문에 나머지 값은 undefined가 출력되는 것을 확인할 수 있다.
그래서 파라미터에 값이 전달되지 않을 경우를 조건문으로 줘서 기본값을 출력하는 방법을 사용하고 있다.
function printName(name, age) { if(age === undefined) { age = '20'; } console.log(`${name}님의 나이는 ${age}살입니다! :)`); } printName('dotori');
위에처럼 조건문으로 default 값을 지정할 수 있지만,
애초에 매개변수가 들어올 때 값이 undefined 일 경우에
default 값을 지정해놓으면, 사용자가 parameter를 전달하지 않을 때,
정의해 놓은 값으로 대체되게 된다.function printName(name, age = 21) { console.log(`${name}님의 나이는 ${age}살입니다! :)`); } printName('dotori');
...args : ... 3개를 쓰게되면, rest parameter라고 부른다.
...으로 값을 받아오면, 배열의 형태로 값이 전달된다.
for loop
function hello(...args) { for(let i=0; i<args.length; i++) { console.log(`Hello myName is ${args[i]}`); } } hello('Judy', 'chip', 'dotori', 'mango', 'candy');
for ... of
function hello(...args) { for(let el of args) { console.log(`Hello myName is ${el}`); } } hello('Judy', 'chip', 'dotori', 'mango', 'candy');
forEach
function hello(...args) { args.forEach((arg) => console.log(`Hello myName is ${arg}`)); } hello('Judy', 'chip', 'dotori', 'mango', 'candy');
hello 함수를 호출할 때 5개의 인자를 넘겨주고 있다.
그러면, 함수의 매개변수로 5개의 인자가 들어올 때 ...로 값을 받아오면['Judy', 'chip', 'dotori', 'mango', 'candy'] 이렇게 배열의 형태로 값이 받아진다.
밖에서는 안이 보이지 않고,
안에서만 밖을 볼 수 있다.let globalVar = 'global'; // global variable function print() { let str = 'hello'; // local variable console.log(str); console.log(globalVar); } print(); console.log(str);
함수는 값을 리턴하면 함수를 실행한 결과의 값을 리턴을 통해 사용할 수 있다.
function sum(num1, num2) { let result = num1 + num2; return result; //만약 함수안에 return 문이 없다면 // return undefined; 와 똑같다! } let sumResult = sum(7, 8); // 15 console.log(`sum: ${sum(7, 8)}`); // sum: 15
리턴을 할 때, 좋지 않은 경우를 먼저 살펴볼 것이다.
결제할 금액이 100만원 초과일 경우 10% 할인된 금액을 할인한 금액으로 알려주는 함수를 작성한다.
function discountPay(amount) { let discount = amount; //{ } 블럭 안에서 로직을 많이 작성하게되면, 가독성이 떨어진다. if(amount > 1000000) { let discount = amount - amount/10; } return discount; } console.log(`계산할 금액은 ${discountPay(700000)}원 입니다. :)`);
함수 안에서 조건문을 if-else로 계속해서 로직을 많이 작성하게되면
가독성이 많이 떨어지기 때문에 조건이 맞지 않을 때는 빨리 리턴을 해서 함수를 종료시키고, 조건이 맞을 때만 함수를 실행할 수 있도록 코드를 작성하는 것이 좋다고 한다.
- 조건이 맞지 않는 경우
- 값이 undefined인 경우
- 값이 -1 인 경우 빨리 리턴해버리고
- 미리 조건이 맞지 않는 경우를 해결 한 다음에 필요한 로직을 실행하는 것이 좋다.
아래의 코드는 결제할 금액이 100만원 미만일 경우 함수를 종료시키고,
결제할 금액이 100만원 초과일 경우 10% 할인된 금액을 할인한 금액으로 알려주는 함수를 작성한다.function discountPay(amount) { let discount = amount; if(amount < 1000000) { return discount' } discount = amount - amount/10; return discount; } console.log(`계산할 금액은 ${discountPay(700000)}원 입니다. :)`);
- function 키워드를 이용해서 함수를 만들고 변수에 할당할 수 있다.
- 함수를 표현하기 전까지는 함수를 호출할 수 없다.
- 함수 선언식과 비교해야 할 점은 함수 선언식으로 만든 함수는 함수를 만들기 이전줄의 코드에서 함수를 호출할 수 있다. 호이스팅 개념때문이다.
let print = function() { //anonymous function console.log('Hello JavaScript'); } print(); let print2 = print; print2();
콜백 함수는 어떤 조건에 따라 실행할 함수를 함수안에 매개변수로 전달하는 것을 말한다.
아래의 함수는 나이에 따라 실행되는 함수가 다르다.
function agePass(age, ageYes, ageNo) { if(age > 14) { ageYes(); } ageNo(); } let ageYes = function() { console.log('해당 놀이기구 탑승이 가능한 나이입니다. :)'); }; let ageNo = function() { console.log('해당 놀이기구를 탑승하기에 너무 어립니다. :('); }; agePass(20, ageYes, ageNo); agePass(10, ageYes, ageNo);
function expression을 사용하게 되면, 변수를 선언하고, function 키워드도 사용해야 되기 때문에 번거로울 수 있다고 한다.
const helloLang = funtion() { console.log('hello JavaScript!'); } const sum = function(num1, num2) { let numSum = num1 + num2; console.log(numSum); return numSum; }
함수를 간결하게 만들어 주는 것이 Arrow function이다.
위의 코드를 바꿔 볼 것이다.
- function 키워드를 지운다.
- { } 블럭을 지운다.
- 코드를 한 줄로 정리한다.
- ( ) 소괄호 다음에
=>
를 넣는다.const helloLang = () => console.log('hello JavaScript!');
const sum = (num1, num2) => console.log(num1 + num2);
위의 arrow function은 한 줄로 끝낼 수 있는 코드라서 { }를 생략하고, return 도 생략할 수 있었다.
아래의 코드는 함수 안에서 다양한 작업을 해야될 때는 {} 블록을 사용하고, return 키워드를 꼭 사용해야 된다.
const calculator = (operator, num1, num2) => { let result = 0; if(operator === '+') { result = num1 + num2; } else if(operator === '-') { result = num1 - num2; } else if(operator === '*') { result = num1 * num2; } else if(operator === '/') { result = num1 / num2; } return result; } calculator('+', 30, 10); calculator('-', 70, 24); calculator('*', 3, 10); calculator('/', 20, 4);
아래와 같이 함수를 선언하게 되면, hello()라고 함수를 선언해야 된다.
function hello() { console.log('IIFE'); }
함수를 선언함과 동시에 바로 호출하기
- 함수의 선언을 ( ) 괄호로 묶는다.
- 그리고 함수를 호출하듯이 끝에 ( ); 괄호를 또 준다.
(function hello() { console.log('IIFE'); })();