728x90
목차
013
callback 함수
- 함수의 매개변수로 함수를 실행시킬 수 있다.
- 함수의 코드를 작성하다가 함수의 매개변수로 전달받은 함수를 필요한 순간에 실행시킨다.
function test(callback) { // 함수를 매개변수로 전달받을 함수 test
console.log("1번 작업 끝");
console.log("2번 작업 끝");
if(true){
callback(); // 값이 true일때 매개변수로 전달받은 함수인 test2를 실행한다.
}
}
function test2() { // 매개변수로 전달될 함수 test2
console.log("나는 콜백함수야!");
}
test(test2); //test함수의 실행식. 함수 test2를 매개변수로 받는다.
let arr2 = {
map : function(callback){ // 개발자가 임의로 객체를 만들 수 있다.
//해당 함수의 매개변수가 몇개가 들어가는지 알 수 있다.
//매개변수 안 받는 함수인데 매개변수를 전달하면 터진다.
if(callback.length == 1) // 매개변수로 받은 값의 길이가 1개일 경우 실행
{
let a = 2;
console.log("나는 map 매개변수는 한 개라고 알고있어." + a + "<- 결과야")
callback(a); // 변수 a의 값을 가지고 객체 map을 실행시킨 함수로 돌아간다. 괄호앞에 이름은 함수의 매개변수 이름과 동일해야 한다.
}
else if(callback.length == 2){ // 매개변수로 받은 값의 길이가 2개일 경우 실행
let a= 2;
let b = 3;
console.log("나는 map함수야 내가 받은 콜백함수에는 매개변수 2개를 넣는다고 전달 받았어.");
callback(a,b); // 변수 a,b의 값을 가지고 객체 map을 실행시킨 함수로 돌아간다.
}
else{ // 변수의 개수가 2개가 넘어가면 실행한다.
console.log("너무 많아")
}
}
}
arr2.map(function(a){ // 객체 map의 함수의 매개변수로 a가 대입된다.
console.log("나는 콜백함수야 전달받은 매개변수는 " + a + "이거야") //객체 map의 함수에서 돌려받은 a의 값을 대입한다.
})
arr2.map(function(a,b){
console.log("나는 콜백함수야 전달받은 매개변수는 " + a + "," + b + "이거야") // 결과값 23. //객체 map의 함수에서 돌려받은 a의 값을 대입한다.
})
arr2.map(function(a,b){
console.log("나는 콜백함수야 전달받은 매개변수는 ",a + b , "이거야") // ,를 넣을 경우 타입을 보장해주므로 결과값 5
})
arr2.map(function(a,b,c){
console.log("나는 콜백함수야 전달받은 매개변수는 ",a + b + c, "이거야") //별도로 돌려받는 값이 없으므로 실행하지 않는다.
})
function temp(fruit){
if(fruit.length === 0){ // 전달된 매개변수의 개수가 0개인 경우 실행. temp2
fruit(); // temp2로 돌아가서 실행한다.
}
else if(fruit.length === 1){ // 전달된 매개변수의 개수가 1개인 경우 실행. temp3
let temp = "사과";
fruit(temp) // 해당 함수의 변수 temp값을 함수 temp2의 매개변수로 대입시킨다.
}
else if(fruit.length === 2){ // 전달된 매개변수의 개수가 2개인 경우 실행. temp4
let temp = "딸기";
let temp2 = "바나나";
fruit(temp, temp2); // 해당 함수의 변수 temp, temp2의 값을 함수 temp4의 매개변수로 대입시킨다.
}
else{ // 전달된 매개변수의 개수가 3개 이상일 경우 실행 temp5
console.log("너 매개변수 초과야 난 두개만 받을 수 있어. 에러!");
}
}
function temp2(){ //함수 temp의 매개변수로 전달할 값이 없다.
console.log("난 콜백함수야");
}
function temp3(v){ //함수 temp의 매개변수로 v를 전달한다.
console.log("난 콜백함수야", v + "를 받았어");
}
function temp4(v,b){ //함수 temp의 매개변수로 v,b를 전달한다.
console.log("난 콜백함수야", v + "를 받았어", b + "도 같이 받았어" );
}
function temp5(v,b,c){ //함수 temp의 매개변수로 v,b,c를 전달한다.
console.log("난 콜백함수야", v + "를 받았어", b + "도 같이 받았어", c );
// 함수 temp에서 매개변수 값을 대입받지 않았으므로 실행되지 않는다.
}
temp(temp2);
temp(temp3);
temp(temp4);
temp(temp5);
👩🏫코드예시_구구단
//객체 선언
let obj2 = {
gugu : function(callback){ //객체 gugu안에 메소드 생성
switch(callback.length) { //매개변수 callback의 길이가 조건.
case 1: // 콜백함수에서 전달받는 매개변수의 길이가 1개일 경우 실행
callback(2); // 콜백함수에 매개변수 값을 2로 전달하여 실행시킨다.
break;
case 2: // 콜백함수에서 전달받는 매개변수의 길이가 2개일 경우 실행
callback(2); // 콜백함수에 매개변수 값을 2로 전달하여 실행시킨다.
callback(3); // 콜백함수에 매개변수 값을 3으로 전달하여 실행시킨다.
break;
case 3: // 콜백함수에서 전달받는 매개변수의 길이가 3개일 경우 실행
callback(2); // 콜백함수에 매개변수 값을 2로 전달하여 실행시킨다.
callback(3); // 콜백함수에 매개변수 값을 3으로 전달하여 실행시킨다.
callback(4); // 콜백함수에 매개변수 값을 4로 전달하여 실행시킨다.
break;
default: //콜백함수에서 전달받는 매개변수의 길이가 4개이상일 경우 실행
console.log("너 매개변수 갯수 확인해");
break;
}
}
}
// 어떻게 만들어도 상관은 없지만 기능 단위로 함수를 만드는 습관을 가지는게 좋다.
function temp6(a){ //객체 gugu의 함수문 안의 switch에서 case 1 실행
for (let i = 1; i < 10 ; i++){
console.log(`${a} x ${i} = ${a * i}`);
}
}
function temp7(a,b){ //객체 gugu의 함수문 안의 switch에서 case 2 실행
for (let i = 1; i < 10 ; i++){
console.log(`${a} x ${i} = ${a * i}`);
}
}
function temp8(a,b,c){ //객체 gugu의 함수문 안의 switch에서 case 3 실행
for (let i = 1; i < 10 ; i++){
console.log(`${a} x ${i} = ${a * i}`);
}
}
function temp9(a,b,c,d){ //객체 gugu의 함수문 안의 switch에서 default 실행
for (let i = 1; i < 10 ; i++){
console.log(`${a} x ${i} = ${a * i}`);
}
}
obj2.gugu(temp6);
obj2.gugu(temp7);
obj2.gugu(temp8);
obj2.gugu(temp9);
스택과 큐
스택(Steck)
- 데이터의 삽입과 삭제가 한쪽 끝에서만 이루어지는 자료구조
- 선입후출(FILO: First-In-Last-out)구조 - 가장 먼저 입력된 데이터가 가장 나중에 제거된다.
- 데이터를 사용하기 위해서 잠시 저장 해놓은 것이다.
스택 오버플로(Steck-overflow)
- 삽입연산을 수행할 때 발생한다.
- 스택을 위해 할당된 저장공간을 초과해서 더 이상 데이터를 삽입할 수 없는 현상이다.
스택 언더플로(Steck-underflow)
- 삭제연산을 수행할 때 발생한다.
- 스택에 데이터가 존재하지 않으면 삭제가 일어나지 않는 현상이다.
- 데이터가 없는데도 삭제를 진행해서 값을 얻어내려고 하면 더 이상 값이 반환되지 않는다.
큐(Queue)
- 선형리스트의 한쪽 끝에서는 데이터의 삭제만 이루어지고, 다른 한쪽 끝에서는 데이터의 삽입만 이루어지는 자료구조
- 선입선출(FIFO: First-In-First-out)특징을 가진다.
큐 오버플로(Queue-overflow)
- 삽입연산을 수행할 때 발생한다.
- 큐을 위해 할당된 저장공간을 초과해서 더 이상 데이터를 삽입할 수 없는 현상이다.
큐 언더플로(Queue-underflow)
- 삭제연산을 수행할 때 발생한다.
- 큐에 데이터가 존재하지 않으면 삭제가 일어나지 않는 현상이다.
- 데이터가 없는데도 삭제를 진행해서 값을 얻어내려고 하면 더 이상 값이 반환되지 않는다.
콜 스택(call Stack)
- 자바스크립트 코드가 실행되며 생성되는 실행 컨텍스트(Execution Context)를 저장하는 자료구조이다.
- 컴퓨터의 메모리 크기나 운영체제 등에 따라 크기가 다르다.
- 콜 스택의 실행
- 함수를 호출하면 실행 컨텍스트가 생성되고, 이를 콜 스택에 추가한 다음 함수를 수행하기 시작
- 함수에 의해 호출되는 모든 함수(내부 함수)는 콜 스택에 추가되고 해당 위치에서 실행
- 함수의 실행이 종료되면 해당 실행 컨텍스트를 콜 스택에서 제거한 후 중단된 시점부터 다시 시작
- 만약 스택이 할당 된 공간보다 많은 공간을 차지하면 스택오버플로우(Stack overflow)에러 발생
- 예) 함수를 무한으로 실행할 때 나올 수 있다.
function dog(){ // 두 번째 함수 실행
console.log("dog"); // 첫 번째 console 값 노출
}
function cat(){ // 세 번째 함수 실행
console.log("cat"); // 세 번째 console 값 노출
}
function bird(){ // 첫 번째 함수 실행
dog(); // 함수 dog 실행문 실행
console.log("bird"); // 두 번째 console 값 노출
cat(); // 함수 cat 실행문 실행
}
bird(); // 함수 bird 실행문 실행
/*작업 순서
01. 16행 / bird 함수 실행문이 동작할 때 까지 모든 함수를 무시
02. 9행 / bird 함수 호출. bird 함수를 호출하여 생성 된 실행 컨텍스트를 콜 스택에 추가
03. 10행 / bird 함수 내 코드 읽기 시작. 함수 dog 실행문 동작.
04. 1행 / dog 함수 호출. dog 함수를 호출하여 생성 된 실행 컨텍스트를 콜 스택에 추가
05. 2행 / console값 노출. dog 함수를 모두 읽음. 해당 실행 컨텍스트 제거
06. 10행 / dog 함수가 호출된 라인으로 돌아와 그 뒤에 코드 계속 실행.
07. 11행 / console값 노출.
08. 12행 / cat 함수 호출. cat 함수를 호출하여 생성 된 실행 컨텍스트를 콜 스택에 추가
09. 6행 / console값 노출. cat 함수를 모두 읽음. 해당 실행 컨텍스트 제거
10. 12행 / cat 함수가 호출된 라인으로 돌아옴. bird 함수 종료로 해당 실행 컨텍스트 제거 */
// 결과: 'dog', 'bird', 'cat'
- 콜스텍을 확인하는 방법(chrom으로 해보)
- 브라우저 개발자모드(f12) > 디버깅모드 활성화(ctrl + f8) > 함수나 코드 줄의 옆에 왼쪽 코드줄 번호에 클릭. 브레이크 포인트가 찍힌다. 이 브레이크 포인터는 코드가 실행되다가 해당 포인트에 도달하면 잠시 실행을 멈춘다. > 재생버튼을 누르면 다름 포인트가 있는 곳까지 실행하다가 또 멈춘다. > call stack 탭에서 확인 가능
- 작업의 디버깅에 용이하다.
실행 컨텍스트(execution context)
- 실행할 코드에 제공할 환경 정보들을 모아놓은 객체로 자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념
- 실행 컨텍스트는 자바스크립트 코드가 실행되는 환경이다. 모든 자바스크립트 코드는 실행컨텍스트 내부에서 실행된다고 생각하면 된다.
실행 컨텍스트의 생성
- 자바스크립트 엔진이 스크립트를 처음 마주할 때 전역 컨텍스트 생성하고 콜 스택에 push
- 엔진이 스크립트를 읽어내려가면서 함수 호출을 발견할 때마다 함수의 실행 컨텍스트를 콜 스택에 push
- 함수 실행 컨텍스트는 함수가 선언될 때가 아니라 실행할 때 만들어진다.
- 실행 컨텍스트를 만들 수 있는 방법은 전역공간, 함수, eval() 함수가 있다.
- eval 함수는 문자열로 된 자바스크립트 코드를 전달하면 그게 그대로 실행되는 함수이다.
- 속도나 보안이 좋지 않아 현재는 거의 쓰지 않는다고 한다.
- 자동으로 생성되는 전역공간과 eval을 제외하면 실행 콘텍스트가 생성되는 시점은 곧 함수를 실행하는 시점이다.
실행 컨텍스트의 종류
전역 실행 컨텍스트
- 전역 영역에 존재하는 코드이다.
- 모든 스크립트 코드는 전역 실행 컨텍스트 안에서 실행된다.
- 프로그램에 단 한 개만 존재하며 실행 컨텍스트의 기본이다. 함수 밖에 있는 코드는 전역 실행 컨텍스트에 존재한다.
- 브라우저의 경우에는 window객체, Node.js의 경우에는 global객체가 곧 전역 실행 컨텍스트가 된다.
함수 실행 컨텍스트
- 함수가 실행되면 함수 실행에 해당하는 실행 컨텍스트가 생성되고, 자바스크립트 엔진에 있는 콜 스택에 차곡차곡 쌓이게 된다.
- 함수가 실행될 때 마다 생성된다. 함수의 실행 정보를 가지고 있다.
eval( ) 실행 컨텍스트
- eval 함수로 실행되는 코드
화살표함수(arrow function)
- ES6에서 새로나온 함수의 방식이다.
- function키워드를 생략할 수 있으며 함수의 매개변수가 1개라면 괄호( )를 생략할 수 있다.
- 함수 바디가 표현식 하나라면 중괄호와 return문을 생략할 수 있다.
const func1 = function() { const num = 10; };
const func1 = () => { const num = 10; }; // function 키워드 생략 가능
const func2 = function(num) {
for(let i = 0; i < 10; i++) { num++; }
return num;
};
const func2 = num => { // 함수의 매개변수에 괄호 생략 가능
for(let i = 0; i < 10; i++) { num++; }
return num;
};
const func3 = function (num) { return `입력된 숫자는 ${num}입니다.`; };
const func3 = num => `입력된 숫자는 ${num}입니다.`; // 중괄호와 return 문 생략 가능
- 화살표 함수는 항상 익명함수이다.
this 함수
- 자바스크립트 객체를 참조하는 특별한 구문이다.
- this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수(self-reference variable)이다.
// 객체 안의 메소드 this는 이 메소드가 포함된 object를 가리킨다.
let A = {
prop: 'Hello',
sayHello: function() {
console.log( this.prop ); /* 메소드 sayHello안의 this는 A의 객체가 되어
a.prop의 값인 'Hello'를 전달받아 콘솔로 출력한다. */
}
};
A.sayHello(); //"Hello"
let A = {
prop: 'Hello',
sayHello: function() {
console.log( this.prop );
}
};
let B = A.sayHello();
console.log(B); // undefined
/*변수 B에 A.sayHello가 담길 때 sayHello()와 A와의 관계가 상실됐기 때문이다.
이럴때 필요한 것이 바로 "데이터 바인딩"이다.*/
let B = A.sayHello.bind(A);
console.log(B); // Hello
//A.sayHello()를 전달할 때 A.sayHello.bind(A)와 같이 A까지 바인딩시켜서 보내면 된다.
- this는 코드 어디서든 참조할 수 있다.
- 하지만 this는 객체의 프로퍼티(객체 안에 선언된 이름과 값으로 이루어진 한 쌍)나 메서드를 참조하기 위한 자기 참조 변수이므로 일반적으로 객체의 메서드 내부 또는 생성자 함수 내부에서만 의미가 있다.
- this가 가리키는 값, 즉 this의 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.
- 바인딩? : 식별자와 값을 연결하는 과정을 말한다.
- this를 전역변수와 지역변수로 사용할 수 있다.
- 전역변수 this
- 전역범위에 항상 존재하는 객체를 의미한다. javascript에서 전역객체는 항상 window라는 전역객체를 참조
- 지역변수 this
- 객체의 메소드 안에서 선언된 this를 말한다. 지역 변수로 선언된 this는 선언된 객체를 참조한다.
- 전역변수 this
let d = () => {
console.log(this); // 변수 d의 화살표함수 내에서 선언된 this는 전역범위를 가진다.
}
let obj = {
a : function(){
b();
console.log(this); // 변수 a의 this가 obj객체 안에 있는 메소드 a안에서 선언되므로 객체가 노출
let c = () => {
console.log(this); // 변수 c의 화살표 함수가 obj객체안에 있는 메소드 a안에서 this가 선언되었기 때문에 객체로 노출
}
c();
d(); // 변수 d의 this가 전역공간에서 선언되었으므로 window가 객체로 노출된다.
}
}
function b() {
console.log(this); // this가 객체를 가리키려면 객체 안에 있는 메소드안에서 this가 선언되어야 한다.
// 전역공간에 있는 해당 THIS는 WINDOWS 객체를 가리킨다.
}
obj.a();
- 일반함수와 화살표함수의 차이는 this의 차이라고 할 수 있다.
- 일반 함수의 this: 함수가 실행될 때 실행하는 위치(스코프)에서 this를 가져온다. (다이나믹 스코프)
- 화살표 함수의 this: 화살표 함수 내부의 this는 화살표 함수를 선언한 위치에서 this를 가져온다. (렉시컬 스코프)
비동기함수
- 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성이다.
- 다른 코드들과 함께 동기적으로 실행되지 않는다.
- 순차적으로 실행되지 않고 작업을 하는 도중에도 다른 작업이 가능하다.
- 예) Node.js
- 서버에서 값을 가져오는 동안 웹페이지가 멈춰있지 않고 다른 작업들은 정상적으로 돌아간다.
- 비동기: 서버에서 값을 가져오는 작업
- 동기: 페이지가 돌아가는 것.
- 예) Node.js
setTimeout 함수
- 코드를 바로 실행하지 않고 일정 시간 기다린 후 실행한다.
- 문법 (매개변수 2개)
- setTimeout(실행할 코드를 담고있는 함수, 시간(ms)); 1000 == 1초.
- setTimeout(function(){console.log("나는 비동기함수. 1초 뒤에 실행 돼.");}, 1000);
- 문법 (매개변수 3개 이상)
- 매개변수 3번째 값부터는 가변인자를 받는다.
- setTimeout(실행할 코드를 담고있는 함수, 시간(ms), 가변인자); 1000 == 1초.
- 첫번째 인자인 함수가 인자를 받는 경우 이 함수에 넘길 인자를 명시한다.
function add(x, y) { // setTimeout에서 첫 번째 인자로 받을 함수 add선언
console.log(x + y); // 콘솔로 x + y 의 결과값을 노출한다.
}
setTimeout(add, 2000, 7, 4); /* 함수 add에 x값을 7로, y값을 4로 대입하여 7 + 4의 결과값을
2초 뒤에 노출한다.*/
//결과: 11
동기처리
- 우선순위 작업이 끝날 때까지 기다리는 동안 준비상태로, 다른 작업을 할 수 없다.
- 순차적으로 실행된다.
❗변수 선언시 변수 타입을 지정하지 않을 경우, 묵시적으로 window 객체가 된다.
//let, var, const꼭 써야 한다고 했는데 쓰지 않을 경우 자동으로 window 객체가 된다.
//window객체
let a = "";
function temp6(){
let g = "";
c = "aa"; // 변수 타입을 선언하지 않으면 window객체의 키값으로 추가된다. 이러면 큰일나고 찾을 수가 없다.
}
temp6();
console.log(window.c); // window의 키값이므로 변수 c의 값인 'aa'가 잘 확인된다.
console.log(c); // window는 전역 객체이므로 노출에 문제는 없다.
console.log(g); // 함수 temp6에 있는 지역변수 g는 전역범위에서 접근할 수 없다.
더보기
- callback
- 실행컨텍스트
- 콜 스택
- 화살표 함수
- this 함수
- 비동기 함수
- setTimeout
728x90