juni
콜백함수 본문
//콜백 함수 -> 다른 코드의 인자로 넘겨주는 함수
// setTimeout(function () {
// console.log("hi")
// },1000)
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(function (number) {
console.log(number);
});
//제어권 / 호출 시점에대한 제어권을 갖는다.
//setInterval() : 반복해서 매개변수로 받은 콜백함수의 로직을 수행
let conut = 0;
let cbFunc = function () {
console.log(conut);
if (++conut > 4) clearInterval(timer);
};
//setInterval의 반복을 멈추기위한 timer 선언
let timer = setInterval(cbFunc, 300);
// 인자에대한 제어권을 갖는다
// map함수 : 배열에대한 api(메서드) -> 배열에대한 하나하나를 로직에의해 순회하고 가공하여 새로운 배열을 return
let newArr = [10, 20, 30].map(function (currentValue, index) {
console.log(currentValue, index);
return currentValue + 5;
});
console.log(newArr);
// setTimeout은 내부에서 콜백 함수를 호출할 때, call 메서드의 첫 번째 인자에
// 전역객체를 넘겨요
// 따라서 콜백 함수 내부에서의 this가 전역객체를 가리켜요
setTimeout(function () {
console.log(this);
}, 300); // Window { ... }
// forEach도 마찬가지로, 콜백 뒷 부분에 this를 명시해주지 않으면 전역객체를 넘겨요!
// 만약 명시한다면 해당 객체를 넘기긴 해요!
[1, 2, 3, 4, 5].forEach(function (x) {
console.log(this); // Window { ... }
});
//addEventListener는 내부에서 콜백 함수를 호출할 때, call 메서드의 첫 번째
//인자에 addEventListener메서드의 this를 그대로 넘겨주도록 정의돼 있어요(상속)
// document.body.innerHTML += '<button id="a">클릭</button';
// document.body.querySelector("#a").addEventListener("click", function (e) {
// console.log(this, e); // this가 부모 객체 -> document.body.querySelector 를 가리킴
// });
Array.prototype.map123 = function (callback, thisArg) {
//맵 함수 인자값 callback함수와 this ->무조건
//map 함수에서 return할 결과 배열
let mappedArr = [];
for (var i = 0; i < this.length; i++) {
// call의 첫 번째 인자는 thisArg가 존재하는 경우는 그 객체, 없으면 전역객체
// call의 두 번째 인자는 this가 배열일 것(호출의 주체가 배열)이므로,
// i번째 요소를 넣어서 인자로 전달
var mappedValue = callback.call(thisArg || global, this[i]);
mappedArr[i] = mappedValue;
}
return mappedArr;
};
const newArr = [1, 2, 3].map123((item) => {
return item * 2;
});
console.log(newArr);
let obj = {
vals: [1, 2, 3],
logValues: function (v, i) {
if (this === global) {
console.log("this->global");
} else {
console.log(this, v, i);
}
},
};
//method로써 호출은 호출만 하는거임
// ->obj.logValues(1, 2);
//forEach , map , filter : 2개의 매개변수 중 첫번째는 기준이되는 배열의 n번째요소(4) , 인덱스로는 그 요소의 인덱스 (logValues)
// logValues()는 실행한 결과값이 들어가므로 함수를 매개변수로(콜백함수)사용시 함수 자체를 넣어야함
[4, 5, 6].forEach(obj.logValues);
//콜백 함수 내부의 this에 다른 값 바인딩하기
// var obj1 = {
// name: "obj1",
// func: function () {
// var self = this; //이 부분!
// return function () {
// console.log(self.name);
// };
// },
// };
// // 단순히 함수만 전달한 것이기 때문에, obj1 객체와는 상관이 없어요.
// // 메서드가 아닌 함수로서 호출한 것과 동일하죠.
// var callback = obj1.func();
// setTimeout(callback, 1000);
// 결과만을 위한 하드코딩 -> 최대한 지양해야하는 코딩임
// var obj1 = {
// name: "obj1",
// func: function () {
// console.log(obj1.name);
// },
// };
// setTimeout(obj1.func, 1000);
//제대로 시작
var obj1 = {
name: "obj1",
func: function () {
var self = this; //이 부분!
return function () {
console.log(self.name);
};
},
};
var obj2 = {
name: "obj2",
func: obj1.func,
};
var callback2 = obj2.func();
setTimeout(callback2, 1500);
//원활한 this binding 방법
var obj3 = { name: "obj3" };
var callback3 = obj1.func.call(obj3);
setTimeout(callback3, 2000);
// bind : this를 바인딩해서 새로운 함수를 return -> 함수를 만들어 놓을 때 유용
var obj1 = {
name: "obj1",
func: function () {
console.log(this.name);
},
};
// let boundObj1 = obj1.func.bind(obj1);
// setTimeout(boundObj1, 1000); // obj1 객체가 this로 묶이면서 5번째 줄 this가 무조건 obj1이 된다
//함수 자체를 바인딩 하는 방법
let obj2 = { name: "obj2" };
setTimeout(obj1.func.bind(obj2), 1500); // 원하는대로 새로운 this를 바인딩함
// new 연산자로 호출한 Promise의 인자로 넘어가는 콜백은 바로 실행
// 그 내부의 resolve(or reject) 함수를 호출하는 구문이 있을 시
// -> 둘 중 하나가 실행되기 전까지는 다음(then) , 오류(catch)로 진행x
// 비동기작업 완료시 비로소 resolve , reject 호출
new Promise(function (resolve) {
setTimeout(function () {
let name = "espreso";
console.log(name);
resolve(name);
}, 500);
})
.then(function (prevName) {
//내부에서도 새로운 Promise를 생성
return new Promise(function (resolve) {
setTimeout(function () {
let name = "americano";
console.log(name);
resolve(name);
}, 500);
});
})
.then(function (prevName) {
//내부에서도 새로운 Promise를 생성
return new Promise(function (resolve) {
setTimeout(function () {
let name = "cafeMocha";
console.log(name);
resolve(name);
}, 500);
});
});
//비동기화 refectoring (효율화)
let addCoffee = (name) => {
return function (prevName) {
//내부에서도 새로운 Promise를 생성
return new Promise(function (resolve) {
setTimeout(function () {
//백틱 , if문 등 활용
let newName = prevName ? `${prevName}, ${name}` : name;
console.log(newName);
resolve(newName);
}, 500);
});
};
};
addCoffee("espreso")() // Promise 리턴을 위해 () 를 추가
.then(addCoffee("americasno"))
.then(addCoffee("cafemocha"))
.then(addCoffee("cafelatte"));
var addCoffee = function (prevName, name) {
setTimeout(function () {
coffeeMaker.next(prevName ? prevName + ", " + name : name);
}, 500);
};
// 함수* -> 제너레이터 함수 : 실행시 Iterator 객체가 반환
var coffeeGenerator = function* () {
//yield 키워드 만날시 멈추고 addcoffee가 끝날때까지 기다렷다가 next메서드 호출시 진행 -> addcoffee내부에 next메서드 로직 존재
//yield 키워드로 순서 제어
var espresso = yield addCoffee("", "에스프레소");
console.log(espresso);
var americano = yield addCoffee(espresso, "아메리카노");
console.log(americano);
var mocha = yield addCoffee(americano, "카페모카");
console.log(mocha);
var latte = yield addCoffee(mocha, "카페라떼");
console.log(latte);
};
//이터레이터 는 넥스트 메서드로 순회가능
var coffeeMaker = coffeeGenerator();
coffeeMaker.next();
//Promise : then / async await
var addCoffee = function (name) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(name);
}, 500);
});
};
var coffeeMaker = async function () {
var coffeeList = "";
var _addCoffee = async function (name) {
coffeeList += (coffeeList ? ", " : "") + (await addCoffee(name));
};
//promise를 반환하는 함수인경우, await를 만나면 무조건 끝날때까지 대기
await _addCoffee("에스프레소");
console.log(coffeeList);
await _addCoffee("아메리카노");
console.log(coffeeList);
await _addCoffee("카페모카");
console.log(coffeeList);
await _addCoffee("카페라떼");
console.log(coffeeList);
};
coffeeMaker();
'CS' 카테고리의 다른 글
JS 문법 복습 및 React 학습 (0) | 2024.05.13 |
---|---|
JS 문법 복습 (0) | 2024.05.12 |
JS 문법 복습 (0) | 2024.05.10 |
State , Props , useRef , Hooks (0) | 2024.05.06 |
호이스팅, this (0) | 2024.04.29 |