JSConf 2020 당근마켓 배지원정대 퀴즈 풀이 - 오답 노트

modolee·2020년 9월 20일
6

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');

정답

  • O

풀이 과정

  • 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'); // Arrow Func call Window
arrowFunc.apply([1,2], ['apply']); // Arrow Func apply Window
const arrowBind = arrowFunc.bind([1,2], 'bind'); // Arrow Func bind Window
arrowBind();

normalFunc.call([1,2], 'call'); // Normal Func call (2) [1, 2]
normalFunc.apply([1,2], ['apply']); // Normal Func apply (2) [1, 2]
const normalBind = normalFunc.bind([1,2], 'bind'); // Normal Func bind (2) [1, 2]
normalBind();

배지 획득

참고

이벤트 루프

this

profile
기초가 탄탄한 백엔드 개발자를 꿈꿉니다.

0개의 댓글