관리 메뉴

클라이언트/ 서버/ 엔지니어 "게임 개발자"를 향한 매일의 공부일지

[자바스크립트 심화 과정] 실력 확인 테스트 1 : 문제 1~3번 본문

웹 · 앱 개발/자바 스크립트

[자바스크립트 심화 과정] 실력 확인 테스트 1 : 문제 1~3번

huenuri 2024. 11. 28. 18:14

점심을 늦게 먹은 데다 집안일할 게 있어서 하고 나니 4시 반이 넘었다. 지금부터 2시간 동안 열심히 오후 공부를 진행해보려고 한다. 지난 2주 동안 난 자바스크립트를 정말 열심히 공부했다.

오늘은 이 과목을 마무리하는 의미로 테스트 문제를 풀어보려고 한다. 잘 풀 수 있을지 걱정이지만 풀 수 있는 데까지 최선을 다해 볼 것이다.


 

 

 

 

 

테스트 문제 풀기

 


 

 

 

 

문제 1번

 

 

 

 

 

문제는 잘 풀었지만 코드를 분석해보며 해설도 써보겠다.

 

핵심 포인트

 

  • nameChanger는 전역에서 선언된 함수로, 기본적으로 this는 호출 방식에 따라 달라진다.
  • user.nameChanger로 참조할 수 있지만, 호출 방식에 따라 this가 다르게 바인딩된다.

 

보기 분석

1. "nameChanger" 메서드를 호출하면 globalThis의 "name" 필드가 변경된다.

  • user.nameChanger()를 호출하지 않고 단순히 nameChanger()를 호출하면, this는 기본적으로 globalThis(브라우저에서는 window)를 참조한다.
  • this는 호출 방식에 따라 결정되므로, 단순히 nameChanger()를 호출하면 this는 globalThis를 참조하며, 전역 객체의 name 속성을 변경한다.

2. "user" 객체의 "name"을 바꾸려면 "nameChanger.bind(user)"를 호출한다.

  • nameChanger를 user 객체에 바인딩하려면 bind를 사용해야 한다. 이렇게 하면 this가 user로 고정된다.
  • nameChanger.bind(user)를 호출하면 this가 항상 user로 고정되므로, user.name이 변경된다.

3. "user" 객체의 "name"을 비동기적으로 바꾸려면 "setTimeout(user.nameChanger, 0)"을 호출한다.

  • setTimeout(user.nameChanger, 0) 호출 시, user.nameChanger가 독립된 함수로 전달된다. 이 경우, this는 globalThis를 참조한다.
  • setTimeout(user.nameChanger, 0)을 호출하면 this는 user가 아니라 globalThis를 참조하며, globalThis.name이 변경됩니다. user.name은 변경되지 않는다.

 

 

 

 

 

문제 2번

 

 

 

 

 

 

이 문제도 잘 풀었는데 왜 이렇게 되는지 설명은 잘 못하니 문제를 분석하며 풀이를 적어본다.

주어진 코드는 Counter라는 클로저를 사용하여 상태(state)를 관리하고 있다. 각각의 함수는 상태를 직접적으로 업데이트하거나 반환하며, 비동기 및 동기적으로 실행된다.


 

 

핵심 포인트

  1. 초기 상태
    • state.count는 처음에 0으로 초기화된다.
  2. asyncIncrease 함수
    • 비동기적으로 1초(state.timeout = 1000) 후에 state.count를 증가시킵다.
  3. increase 함수
    • 즉시 동기적으로 state.count를 증가시킨다.
  4. getState 함수
    • 현재 상태(state)를 반환한다.
  5. 질문에서의 상황
    • (a)에서는 asyncIncrease 호출
    • (b)에서는 increase를 세 번 호출
    • (c)에서는 2초 후 상태 확인

 

 

 

보기 분석

(a) : counter.getState()를 호출했을 때 state.count의 값은 0이다.

  • asyncIncrease는 1초 후에 동작하므로, 호출 직후 상태는 아직 변경되지 않는다.
  • 따라서, 호출 시점에서 state.count는 0이다.

(b) : counter.getState()를 호출했을 때 state.count의 값은 3이다.

  • increase를 세 번 호출했으므로, 각 호출마다 state.count가 동기적으로 증가한다.
  • 따라서, (b)에서 state.count는 3이다.

(c)에서 counter.getState()를 호출했을 때 state.count의 값은 3이다.

  • (a)에서 호출된 asyncIncrease는 1초 후에 state.count를 증가시킨다.
  • (b)에서 호출된 increase로 인해 state.count는 3으로 증가한다.
  • 2초가 지난 시점에서 (a)의 asyncIncrease가 1을 추가로 증가시키므로, 최종 값은 4이다.

asyncIncrease가 제대로 동작하려면, (d)가 state.count = state.count + 1로 바뀌어야 한다.

  • (d)에서 이미 state.count = currentCount + 1로 구현되어 있다.
  • 이는 상태를 정확히 업데이트하므로 수정이 필요 없다.

 

 

 

 

 

문제 3번

 

 

 

 

 

 

1. AsyncState 함수

  • 상태(state)를 관리하는 클로저이다.
  • updateState(name, age)는 비동기로 상태를 업데이트하며, 랜덤한 timeout(0~999초) 후에 상태를 변경한다.
  • getState()는 현재 상태를 반환한다.

 

2. 초기화 및 사용

const asyncState = AsyncState({ name: "Kim", age: 30 });

 

  • AsyncState 함수 호출로 클로저를 생성한다.
  • 초기 상태는 { name: "Kim", age: 30 }이다.
  • asyncState 객체는 updateState와 getState 메서드를 사용할 수 있다.

 

 

3. (a) 코드: Promise.all 병렬 처리

Promise.all([
  asyncState.updateState("Song", 40),
  asyncState.updateState("Shim", 50),
]).then(() => {
  console.log("state : ", asyncState.getState());
});

 

  1. asyncState.updateState("Song", 40)와 asyncState.updateState("Shim", 50)가 동시에 호출된다.
    • 각각 0~999ms 사이의 랜덤한 시간 후 상태를 업데이트한다.
  2. Promise.all은 모든 updateState 호출이 완료된 후 .then 콜백을 실행한다.
  3. 최종 상태 마지막으로 완료된 Promise에 의해 결정된다.
    • 예를 들어, "Song", 40이 먼저 완료되고 "Shim", 50이 나중에 완료되었다면, 최종 상태는 { name: "Shim", age: 50 }가 된다.

 

4. (b) 코드: 체인 방식의 비동기 호출

asyncState
    .updateState("Song", 40)
    .then(() => asyncState.updateState("Shim", 50))
    .then(() => {
        console.log("state : ", asyncState.getState());
    });

 

 

  1. asyncState.updateState("Song", 40)를 호출한다.
    • 이 호출은 0~999ms 동안 대기 후 상태를 { name: "Song", age: 40 }로 업데이트한다.
  2. 첫 번째 Promise가 완료된 후 .then 콜백에서 asyncState.updateState("Shim", 50)를 호출한다.
    • 다시 0~999ms 동안 대기 후 상태를 { name: "Shim", age: 50 }로 업데이트한다.
  3. 두 번째 Promise가 완료된 후 최종 상태를 콘솔에 출력한다.

 

5. 주요 차이: (a)와 (b)의 동작 비교

(a) : 병렬 처리

  • 두 개의 updateState 호출이 동시에 실행된다.
  • 최종 상태는 가장 늦게 완료된 Promise에 의해 결정된다.
  • 실행 속도가 더 빠릅니다.

(b) : 체인 처리

  • 두 개의 updateState 호출이 순차적으로 실행된다.
  • 최종 상태는 항상 **마지막으로 호출된 updateState**에 의해 결정된다.
  • 실행 속도가 더 느리다.

 

6. Timeout 설정

const timeout = Math.floor(Math.random() * 1000);

 

 

  • updateState는 호출될 때마다 랜덤한 시간(0~999ms)을 기다린다.
  • setTimeout을 사용해 지정된 시간 후에 상태를 업데이트하고, Promise를 resolve한다.

 

 

 

 

 

학습을 마치고

아직 한 문제가 남아있는데 너무 코드가 길어서 다음 포스트에 이어서 진행하기로 했다. 객관식 3문제 주관식 한 문제로 구성되어 있다. 신기하게도 객관식 문제는 모두 다 맞혔다.

어떻게 되는 건지 설명을 하지 못하는데 이제 코드를 보면 결과가 어떻게 될지 감이 잡히는 정도는 되는 것 같다.

 

그동안의 공부가 헛되지 않은 것 같아 정말 기뻤다~