1번 문제
const func = function () {
console.log('당신');
return new Promise((res) => {
res('개발자');
});
};
const execute = func();
console.log('근처의');
setTimeout(() => {
console.log('당근개발자');
}, 0);
execute.then((msg) => {
console.log(msg);
});
정답
풀이 과정
- Call Stack과 Task Queue가 있어서 Event Loop 가 돌면서 Call Stack에 있는 것을 먼저 처리하고 Call Stack이 비어 있다면 Task Queue에 있는 것을 처리한다고 알고 있었음
- 그래서 당연히 setTimeout, Promise 모두 Task Queue에 들어가기 때문에
당신 근처의 당근개발자 개발자
가 정답일 것이라고 생각
- 그런데 보기에 없어서 당황
- JavaScript 이벤트 루프 개념 을 통해서 Microtask Queue의 존재를 확인
- setTimeout은 Task Queue에 넣어서 처리
- Promise의 경우는 Microtask Queue에 넣어서 처리
- Microtask Queue가 Task Queue 보다 우선적으로 처리 되기 때문에
당신 근처의 개발자 당근개발자
가 정답
개념 정리
ES6 이전
- 처리 우선순위 : Call Stack > Task Queue
ES6 이후
- 처리 우선순위 : Call Stack > Microtask Queue > Animation Frames > Task Queue 순으로 실행 (크롬 기준, 브라우저 마다 다를 수 있음)
2번 문제
const obj = {
title: '자바스크립트',
subObj: {
title: 'Javascript',
show(func) {
return func.apply(this);
}
},
show() {
return this.subObj.show(() => {
return this.title;
});
}
}
console.log(obj.show() === '자바스크립트' ? 'O' : 'X');
정답
풀이 과정
obj.show
에서의 this는 obj가 호출하고 있기 때문에 obj
를 가리킴
this.subObj.show
에서의 this는 subObj
를 가리킴
this.subObj.show
에 넘긴 func는 this를 apply 하기 때문에 위에서 확인한 subObj
가 해당 func에서의 this 일 것이라고 생각
- 그래서 this.title을 출력하면 subObj의 title인
'Javascript'
가 출력되고 결과적으로 X가 출력 될 것이라고 생각
- 그러나 오답 ㅠㅠ
- 분명 코어 자바스크립트 3장에서 봤던 내용인데, this가 상위 스코프의 this를 바라본다고만 이해 했음
- this 자체가 없기 때문에 call, apply, bind 메서드를 사용해도 this에 변화가 없는 것이 맞음
- 그렇기 때문에 func로 넘긴 arrow function의 경우 this는 obj를 가리키기 때문에 this.title은
'자바스크립트'
를 출력하게 되고 정답은 O가 된다.
개념 정리
- 화살표 함수 (Arrow Function)를 사용하면 실행 컨텍스트 생성 시 this 바인딩이 제외되어 함수 내부에 this가 없으며 그로 인해 스코프 체인 상 가장 가까운 this에 접근
- 그래서 call, apply, bind 메서드를 사용해도 변경 할 this가 없기 때문에 영향을 받지 않음
const arrowFunc = (method) => {
console.log(`Arrow Func ${method}`, this);
};
const normalFunc = function (method) {
console.log(`Normal Func ${method}`, this);
};
arrowFunc.call([1,2], 'call');
arrowFunc.apply([1,2], ['apply']);
const arrowBind = arrowFunc.bind([1,2], 'bind');
arrowBind();
normalFunc.call([1,2], 'call');
normalFunc.apply([1,2], ['apply']);
const normalBind = normalFunc.bind([1,2], 'bind');
normalBind();
배지 획득
참고
이벤트 루프
this