2020. 6. 3. 20:00ㆍ프론트엔드/JAVASCRIPT
1. Function
-fundamental building block in the program
-subprogram can be used multiple times
-perfirns a task or calculates a value
1-1. Function declaration
function name(param1, param2) {body... return;}
one function === one thing(한 개의 함수는 한 가지의 일만 하도록 작성해야함)
e.g. createCardAndPoint -> createCard, createPoint
function is object in JS (자바스크립트에서 함수는 Object로 간주)
변수에 할당할 수도 있고 파라미터로 전달되고 함수를 리턴도 가능
function printHello() {
console.log("Hello");
}
printHello(); //Hello
function log(message) {
console.log(message);
}
log("Hello@"); //Hello@
자바스크립트에서는 타입이 없기 때문에
log라는 함수의 인터페이스만 보면(log함수가 정의된 정의내용만 파라미터만 보면 )
파라미터로 string이 전달되는건지 number가 전달되는건지 명확하지 않음
자바스크립트에서 log(1234)를 호출하면 파라미터가 number형이지만 string형으로 변환되어 출력은 되겠지만
타입이 중요한 함수라면 자바스크립트는 난해할 수 있음
반면에 타입스크립트를 사용한다면 타입스크립트는 타입이 정의하기 때문에 아주 명확함
1-2. Parameters
premitive parameters: passed by value
(premitive type은 메모리에 value가 그대로 저장되기 때문에 parameter로 value가 그대로 전달됨)
object parameters: passed by reference
(object는 메모리에 reference가 저장되기 때문에 parameter로 object를 가리키는 reference가 전달됨)
function changName(obj) {
obj.name = "coder";
}
const ellie = { name: "ellie" };
changName(ellie); // ellie의 name을 'coder'로 변경
console.log(ellie); //{name: "coder"}
1-3. Default parameters(added in ES6)
// 두 개의 파라미터를 받는 'showMessage'라는 함수를 선언
function showMessage(message, from) {
console.log(`${message} by ${from}`);
}
//'showMessage'를 호출할 때 파라미터를 한 개만 전달
showMessage("showMessage"); //showMessage by undefined
//예전에는 이럴경우를 대비해 파라미터가 undefined일 경우 아래처럼 조건문을 통해 값을 정의
function beforeShowMessage(message, from) {
if (from === undefined) {
from = "unknown";
}
console.log(`${message} by ${from}`);
}
beforeShowMessage("beforeShowMessage"); //beforeShowMessage by unknown
// 하지만 지금은 (ES6부터는) undefined일 경우를 대비해서 전달받을 파라미터 옆에 기본값을 정의
function afterShowMessage(message, from = "unknown") {
console.log(`${message} by ${from}`);
}
afterShowMessage("afterShowMessage"); //afterShowMessage by unknown
1-4. Rest parameters(added in ES6)
여러개의 파라미터를 전달시 배열형태로 파라미터가 전달됨
function printAll(...args) {
for (let i = 0; i < args.length; i++) {
console.log(args[i]);
}
//위의 for Loop를 조금 더 간단하게 출력
for (const j of args) {
console.log(j);
}
//위의 for Loop를 조금 더 간단하게 출력
args.forEach(j => console.log(j));
}
printAll("dream", "coding", "ellie");
//dream
//coding
//ellie
1-5. Local scope
let globalMessage1 = "global1"; //global variable
function printMessage() {
let localMessage1 = "local1";
console.log(localMessage1); //local varible
console.log(globalMessage1);
}
printMessage();
//console.log(localMessage1); //error발생
//local varible를 선언된 함수 바깥에서 출력했기 때문에 error발생
//global1
//local1
let globalMessage2 = "global2"; //global variable
function printMessage2() {
let localMessage2 = "local";
console.log(localMessage2); //local varible
console.log(globalMessage2);
function innerprintMessage2() {
console.log(localMessage2);
let childLocalMessage2 = "childLocal";
}
//console.log(childLocalMessage2); //error발생
//childLocalMessage2는 innerPrintMessage2에 정의되어 있기 때문에 innerPrintMessage2함수의 바깥에서 출력하려 하면 에러발생
}
printMessage2();
-자바스크립트에서 스코프란안에 정의된 변수를 바깥에서는 접근이 불가능하고 바깥에서 선언된 변수는 안에서 접근이 가능
-자바스크립트에서 printMessage2와 같이 중첩된 함수에서 자식의 함수가 부모의 함수에서 정의된 변수에 접근이 가능한 걸 '클로저'라고 함
1-6. Return a value
return type이 없는 함수들은 'undefined'를 return하는 것과 똑같음(return undefined) -> 생략
그러니까 모든 함수는 return undefined이거나 return 값을 지정해서 리턴
function sum(a, b) {
return a + b;
}
const result = sum(1, 2);
console.log(`sum:${sum(1, 2)}`); // sum:3
1-7. Early return, early exit
// bad function : 조건을 만족하는 경우에 먼저 if문에서 긴 로직을 처리
function upgradeUser(user) {
if (user.point > 10) {
//long upgrade logic ...
}
}
//good function : 조건을 만족하지 않는 경우에 먼저 if문에서 return;으로 처리하고 조건을 만족하면 실행하는 로직은 그 뒤에 처리
function upgradeUser(user) {
if (user.point <= 10) {
return;
}
// long upgrade logic ...
}
2. First-class function
functions are treated like any other variable
can be assigned as a value to variable
can be passed as an argument to othher functions
can be retunrned by another function
2-1. Function expression
a function declaration can be called earlier than it is defined. (hoisted)
a function expression is created when the execution reaches it.
const print = function() {
//annoymous function(이름이 없는 함수) <-> named function(이름이 있는 함수)
console.log(`print`);
};
print();
const printAgain = print;
printAgain();
const sumAgain = sum;
console.log(sumAgain(1, 3));
- a function expression은 위와 같이 할당된 다음부터 호출이 가능(변수에 할당 전에 호출시 당연히 에러발생)
- a function declaration는 호이스팅이 되기 때문에 함수가 선언되기 이전에 호출하는 것이 가능(호출 전에 선언된 함수를 위로 끌어올려놓기 때문에 가능:hoist)
2-2. Callback function using function expression
function randomQuiz(answer, printYes, printNo) {
if (answer === "love you") {
printYes();
} else {
printNo();
}
}
// annoymous function
const printYes = function() {
console.log("yes!");
};
// named function
// better debugging in debugger's stack traces (디버깅을 할 때 (stack traces에) 함수이름이 나오게 하려고 주로 named function 사용)
// recursions(함수 안에서 함수 자신 스스로를 부르는 것 : 함수 안에서 또 다른 함수를 호출할 경우 주로 named function 사용)
const printNo = function print() {
console.log("no!");
};
randomQuiz("wrong", printYes, printNo);
randomQuiz("love you", printYes, printNo);
2-3. Arrow function
- always annoymous ( Arrow function은 항상 annoymous function)
- 훨씬 간결하게 표현 가능
// 훨씬 간결하게 표현 가능
const simplePrint = function() {
console.log("simplePrint!");
};
const arrowSimplePrint = () => console.log("arrowSimplePrint!"); //위의 simplePrint 함수를 arrow함수로 표현
const add = function(a, b) {
return a + b;
};
const arrowAdd = (a, b) => a + b; //위의 add 함수를 arrow함수로 표현
// 함수가 한 줄일 경우에는 블럭('{}')없이 표현이 가능하지만 함수 내용이 길어진다면 아래와 같이 표현하는데
// 블럭사용시에는 'return'키워드 사용해서 리턴해야함
const simpleMultiply = (a, b) => {
//do something more
return a * b;
};
2-4. IIFE: Immediately Invoked Function Expression
-일반적으로 함수를 선언했으면 따로 함수를 호출해야만 함수를 실행시킬 수 있는데 IIFE는 선언함과 동시에 실행가능
(function hello() {
console.log("IIFE");
})();
*QUIZ
// function calculate(command, a, b)
// command add, subtract, divide, multiply, reminder
function calculate(command, num1, num2) {
console.log(num1);
if (
(num1 !== null || num1 !== undefined) &&
(num2 != null || num2 != undefined)
) {
num1 = Number(num1);
num2 = Number(num2);
switch (command) {
case "add":
return num1 + num2;
break;
case "subtract":
return num1 - num2;
break;
case "divide":
return num1 === 0 ? "0으로 나눌 수 없습니다" : num1 / num2; // 0/1 불가눙하므로 삼항연산자로 한 번 더 처리
break;
case "multiply":
return num1 * num2;
break;
case "reminder":
return num1 / num2;
break;
default:
return "잘못된 입력값입니다.";
}
} else {
return "계산할 값을 정확히 입력해주세요.";
}
}
calculate("add", "1", "2");
참고 : 드림코딩 by 엘리 유튜브
'프론트엔드 > JAVASCRIPT' 카테고리의 다른 글
[JS] javascript:void(0) 과 # (0) | 2020.06.08 |
---|---|
[JS] 클래스(Class) (0) | 2020.06.04 |
[JS] 반복문(Loops) (0) | 2020.05.31 |
[JS] 연산자(Operator) (0) | 2020.05.31 |
[JS] 데이터 타입(Data Type) (0) | 2020.05.26 |