모던JS딥다이브 공부정리 글입니다.
(p.154)
함수는 일련의 과정을 문으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것
예시
var f = function add(x, y){ return x+y; }
- add: 함수 이름
- 함수 이름은 함수 몸체 내에서만 참조 가능한 식별자
- 생략 가능하며 이 경우 익명 함수라고 한다(<-> 기명 함수)
- x, y: 매개변수 목록
- 각 매개변수는 순서대로 할당.
- 몸체 내에서 변수와 동일하게 취급
- {}
- 함수 몸체는 함수 호출에 의해 실행
리터럴은 값을 생성하기 위한 표기법
함수 리터럴도 평가되어 값을 생성하며 이 값은 객체다. 즉 함수는 객체다.
함수는 객체이지만 일반 객체와 다르다.(18장 정리하고 링크걸기)
😽 함수 정의 방식 4가지
//1. 함수 선언문 function add(x, y){ return x+y; } //2. 함수 표현식 var add = function (x, y){ return x+y; //3. Function 생성자 함수 var add = new Function('x','y','return x+y') //4. 화살표 함수(ES6) var add = (x, y) => x+y;
- 차이에 대해서 알아보자.
function add(x,y){
return x+y;
}
//dir은 함수 객체의 프로퍼티까지 출력
console.dir(add) // f add(x,y)
console.log(add(2,5)) //7
var add = function add(x,y){
return x+y;
}
console.log(add(2,5)) //7
// 기명함수 리터럴을 단독으로 사용하면 함수 선언문으로 해석됨
function add(x,y){
return x+y;
}
// 기명함수 리터럴을 피연산자로 사용하면 함수 리터럴 표현식으로 해석됨
// 이름 생략 가능
(function bar(){console.log('bar')}; //() 그룹 연산자
bar(); 에러.
😽 함수는 함수 이름으로 호출하는 것이 아니라 함수 객ㅊ를 가리키는 식별자로 호출하는 것이다.
var add = function(x,y){
return x+y;
}
console.log(add(2,5)) //7
함수 리터럴의 함수 이름은 생략 가능하며 생략이 일반적이다.
함수 리터럴은 이름으로 호출할 수 없다.
함수 선언문은 표현식이 아닌 문이고 함수 표현식은 표현식인 문이다.
var res = square(5);
function square(number) {
return number * number;
}
var res = square(5); // TypeError: square is not a function
var square = function(number) {
return number * number;
}
함수 호이스팅 때문에 선언문 보다는 표현식으로 함수 정의하는 것을 권장
타입지정 하려면 코드 블록 내에 조건문 넣어두면 됨
ES6부터 매개변수의 기본 값 설정 가능
function add(a=0, b=0,c=0){ return a + b+ c; }
🌼 이상적인 함수는 한 가지 일만 해야하며 가급적 작게 만들어야 한다.
매개변수는 최대 3개 이상을 넘지 않도록 권장
그 이상이면 객체를 인수로 전달하라.
- 반환문의 두 가지 역할
- 함수 실행 중단 후 함수 몸체를 빠져나감
- return 뒤의 평가식을 평가하여 반환한다. 안하면 undefined 반환
(function (){
var a = 3;
var b = 5;
return a * b;
}());
// 피보나치 수열
// 피보나치 수는 0과 1로 시작하며, 다음 피보나치 수는 바로 앞의 두 피보나치 수의 합이 된다.
// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, ...
function fibonacci(n) {
if (n < 2) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
console.log(fibonacci(0)); // 0
console.log(fibonacci(1)); // 1
console.log(fibonacci(2)); // 1
console.log(fibonacci(3)); // 2
console.log(fibonacci(4)); // 3
console.log(fibonacci(5)); // 5
console.log(fibonacci(6)); // 8
// 팩토리얼
// 팩토리얼(계승)은 1부터 자신까지의 모든 양의 정수의 곱이다.
// n! = 1 * 2 * ... * (n-1) * n
function factorial(n) {
if (n < 2) return 1;
return factorial(n - 1) * n;
}
console.log(factorial(0)); // 1
console.log(factorial(1)); // 1
console.log(factorial(2)); // 2
console.log(factorial(3)); // 6
console.log(factorial(4)); // 24
console.log(factorial(5)); // 120
console.log(factorial(6)); // 720
function outer(){
var x = 1;
function inner(){
var y =2;
console.log(x+y);
}
inner();
}
outer();
function repeat(n, f){ // 공통 로직
for(var i=0;i<n;i++){
f(i);
}
}
var logAll = function(i){ // 변경되는 로직
console.log(i);
}
repeat(5, logAll) // 0 1 2 3 4
콜백 함수는 주로 비동기식 처리 모델(Asynchronous processing model)에 사용된다. 비동기식 처리 모델이란 처리가 종료하면 호출될 함수(콜백함수)를 미리 매개변수에 전달하고 처리가 종료하면 콜백함수를 호출하는 것이다.
콜백함수는 콜백 큐에 들어가 있다가 해당 이벤트가 발생하면 호출된다. 콜백 함수는 클로저이므로 콜백 큐에 단독으로 존재하다가 호출되어도 콜백함수를 전달받은 함수의 변수에 접근할 수 있다.
- 이벤트핸들러
- 타임함수
- AJAX
// 순수함수
let count = 0;
function increase(n){
return ++n;
}
count = increase(n) //1
//비순수함수
let count = 0;
function increase(){
return ++count;
}
increase()
console.log(count) // 1
비순수 함수를 사용하면 변경되는 외부 값을 추적하기 어려워진다.
비순수 함수를 최대한 줄이는 것은 부수 효과를 최대한 억제하는 것과 같다.