728x90
1. 함수의 선언과 함수 표현식
- 함수는 항상 값을 반환한다. return 값이 없더라도 undefiend를 반환한다.
- 함수 표현식 : 함수 앞에 변수 붙여주는 것
- 람다식
- IIFE : 즉시 호출 함수 표현식 - 람다식과 유사, 일회용
// 1. 함수 선언
function add1(a, b) {
return a + b;
}
console.log(add1(1, 2));
// 2. 함수 표현식
var add2 = function (a, b) {
return a + b;
};
console.log(add2(3, 4));
// 3.lambda식
// sort() comparator 했던 것
// 4. IIFE
console.log(
(function (a, b) {
return a + b;
})(5, 6)
);
2. 호출과 arguments 객체
- arguments 객체
- 배열같은 객체 : lenth를 제외하곤 배열 property 존재하지 않는다.
- 함수 호출시 params의 개수 및 값을 알 수 있다.
- arguments를 이용한 function은 params가 무제한으로 들어가진다.
== 가변인자와 유사한 역할 수행
function findMax() {
var i;
var max = -Infinity;
console.log(arguments);
console.log(arguments.length);
for (i = 0; i < arguments.length; i++) {
if (arguments[i] > max) max = arguments[i];
}
return max;
}
console.log(findMax(1, 23, 44, 2)); // arguments를 이용한 function은 params가 가변인자 처럼 작동한다.
3. 함수의 오버로딩
- JS는 실질적으로 params에 들어가는 type이란게 없어서 오버로딩 개념이 없다.
- 하지만 굳이 만들려면 if문을 통해서 만들 수 있다.
4. 유효성검사와 매개변수 초기화
- function 호출시 params의 개수가 빠져있을 경우 기본값을 넣어둔다.
- es6 이후 params에 (a=0, b=0) 이렇게 실제 기본값을 넣어 둘 수 있다.
5. 클로저
- 전역변수의 선언으로 인한 변수이름 충돌 문제 해결 과정
- 문제코드
var cnt = 0; // 전역변수 변수이름 충돌가능성 존재
function increaseCnt() {
cnt++;
}
increaseCnt();
increaseCnt();
increaseCnt();
console.log(cnt);
- 해결1
- 문제점 : 지역변수 scope를 줄였지만 매번 0으로 초기화. 외부에서 사용 못함
function increaseCnt() {
var cnt = 0; // 지역변수 scope를 줄였지만 매번 0으로 초기화. 외부에서 사용 못함
cnt++;
}
increaseCnt();
increaseCnt();
increaseCnt();
console.log(cnt); // is not defined error
- 해결2
- 문제점: 내부에서만 사용가능
function closure() {
var cnt = 0; // 지역변수 scope를 줄였지만 매번 0으로 초기화. 외부에서 사용 못함
function increaseCnt() {
cnt++;
console.log(cnt);
}
increaseCnt();
increaseCnt();
increaseCnt();
}
console.log(closure());
console.log(increaseCnt()); // not defined error
- 해결3
- return으로 내부값 반환
function closure() {
var cnt = 0; // 지역변수 scope를 줄였지만 매번 0으로 초기화. 외부에서 사용 못함
return function () {
// 이름 생략가능
cnt++;
console.log(cnt);
};
}
var increaseCnt = closure(); // 함수 표현식
increaseCnt();
// increaseCnt = function(){ var cnt = 0; return function(){} }
- 활용
- 비동기함수 와 콜백 문제점 및 해결
- 비동기함수들이 대부분 내부에 콜백 함수를 가지고 있다.
- 비동기 함수는 해당 함수가 호출되고 비동기 함수내부의 콜백함수로 부터 return되어야되는 값을 당장 호출하지 않고 외부에서 처리해야하는 값을 다 수행한 후에 다 수행한 결과를 토대로, 콜백함수가 외부에서 다 수행한 결과값을 요리해서 반환을 한다.
- 비동기함수와 콜백 함수 <-> closure 구분할 줄 알아야한다.
- 비동기함수는 내부에 변수값 이런게 중요하지 않다. 호출하면 사용한 변수 값의 최종 처리값을 이용
- closure은 outter function 변수를 이용해서 inner function이 값을 호출한다.
// 클로저 함수
function outer() {
const name = 'John';
function inner() {
console.log(`My name is ${name}`);
}
return inner;
}
const innerFunc = outer();
innerFunc(); // My name is John
// 비동기 함수
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i);
}, 0);
}
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i);
}, 0);
}
// 3,3,3 결과가 나온다. - 이유 설명
// 위의 코드의 var은 함수스코프를 가지므로 아래와 같이 분리 가능
var i;
for (i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i);
});
}
// 콜백함수를 가지고 있는 것이 비동기 함수라고 했는데 별거 없다.
// 함수 내부에 함수가 존재하고 내부 함수가 외부 변수를 사용하면 그게 비동기 함수이다.
// 설명
//1. setTimeout()이라는 비동기 함수가 호출
//2. 즉시 수행이 되지 않고 for문의 i를 먼저 수행
//3. 수행 다되면 setTimeout() 콜백함수 호출
//결론 : 그래서 3 만 나오게 됨
var i;
for (i = 0; i < 3; i++) {
console.log("비동기 i 증가 수행: " + i);
setTimeout(function () {
console.log(i);
});
}
// 결과
// 0,1,2,3 -> setTimeout() = 3
// 3 -> setTimeout() = 3 // var i가 최초에 3으로 설정된 후 이게 for문이 끝날때 까지 유지
// 3 -> setTimeout() = 3
// 해결방안
// 1. let을 통해서 loop 걸어주기
// 2. closure 사용
let i; // 전역scope에 위치하므로 3,3,3 나옴
for (i = 0; i < 3; i++) {
console.log("비동기 i 증가 수행: " + i);
setTimeout(function () {
console.log(i);
});
}
// 지역 scope로 걸어서 block이 다 수행된 후 다음 for문 loop 돌도록
for (let i = 0; i < 3; i++) {
console.log("비동기 i 증가 수행: " + i);
setTimeout(function () {
console.log(i);
});
}
// closure
var i;
for (i = 0; i < 3; i++) {
// 제일 외부 function은 비동기 함수가 아니므로 동기함수로 수행
// 내부 setTimeout 비동기함수는 외부function으로 부터 받은 값이 최종값이라고 인식
(function (i) {
setTimeout(function () {
console.log(i);
});
})(i);
}
6. JS와 비동기
- JavaScript에서 비동기 함수가 존재하는 이유는 크게 두 가지
- JavaScript가 싱글 스레드로 동작
- JavaScript는 한 번에 하나의 작업만 처리가능
- 만약 JavaScript에서 오랜 시간이 걸리는 동기 함수를 호출하면 해당 함수가 끝날 때까지 다른 작업을 수행하지 못하고 대기 -> 웹 애플리케이션에서 사용자 경험을 저하시키는 요인
- JavaScript에서는 비동기 함수를 통해 이러한 문제를 해결
-> 비동기 함수를 호출하면 해당 함수는 백그라운드에서 실행되며, JavaScript는 다른 작업을 수행
- JavaScript가 네트워크와 같은 외부 리소스와 상호작용하는 일이 많기 때문
- 네트워크 작업은 일반적으로 시간이 많이 걸리는 작업
- JavaScript에서 네트워크 작업을 동기적으로 처리하면 애플리케이션이 멈춰보일 수 있습니다.
- JavaScript에서는 비동기 함수를 통해 네트워크와 같은 외부 리소스와 상호작용하는 작업을 처리
- JavaScript가 싱글 스레드로 동작
- 비동기 함수 설정 기준
- 특정 메서드가 오래 걸리는지를 판단하기 위해서는 그 메서드가 처리하는 작업의 양과 복잡도, 그리고 실행 환경의 상황 등을 고려 일반적으로 I/O 작업이나 네트워크 요청 등은 시간이 많이 소요되기 때문에 이러한 작업들은 비동기 함수로 처리하는 것이 좋다.
- 개발자가 직접 코드를 실행해보고 시간 측정 도구를 사용해서 해당 메서드의 실행 시간을 측정
- 이를 통해 어느 정도 시간이 걸리는지를 확인하고 최적화를 시도
- 특정 메서드가 오래 걸리는지를 판단하기 위해서는 그 메서드가 처리하는 작업의 양과 복잡도, 그리고 실행 환경의 상황 등을 고려 일반적으로 I/O 작업이나 네트워크 요청 등은 시간이 많이 소요되기 때문에 이러한 작업들은 비동기 함수로 처리하는 것이 좋다.
- 비동기 생성
- 자바스크립트에서는 비동기 함수를 생성하는 방법으로 콜백 함수, Promise, async/await 등을 제공
- 개인이 직접 함수를 만들어 비동기 처리를 할 수도 있으며, 이는 자바스크립트의 유연성과 확장성에 기인
- 하지만 이러한 직접 구현하는 것보다 이미 제공되는 비동기 함수를 사용하는 것이 안전하고 효율적