[JS & ES6 신문법 학습] 변수 연습문제 6개

김범기·2024년 7월 11일

JAVASCRIPT

목록 보기
7/38

변수 연습문제 6개

1~4. 다음 코드의 콘솔창 출력결과는 무엇일까요?

(문제1)

함수();
function 함수() {
  console.log(안녕);
  let 안녕 = 'Hello!';
} 

let을 사용했으므로 undefined가 아닌 오류를 출력함

var: Hoisting시 undefined 할당됨
let, const : Hoisting시 undefined 할당 안됨


(문제2)

함수();
var 함수 = function() {
  console.log(안녕);
  var 안녕 = 'Hello!';
} 

함수 안에서는 var을 사용했으므로 undefined를 출력함
하지만, 함수 또한 var 함수 = 을 이용해서 사용했기에, 함수라는 선언은 되어있지만, 함수안의 function이 할당이 되지 않았기에 함수()를 사용하면 이거 함수 아닌데 왜 함수처럼 사용함? 이라는 오류가 발생한다.


(문제3)

let a = 1;
var 함수 = function() {
  a = 2;
}
console.log(a);

a를 1로 할당했고, 함수 또한 실행하지 않았으므로 1이 출력됨


(문제4)

let a = 1;
var b = 2;
window.a = 3;
window.b = 4;

console.log(a + b);

var b 는 window.b는 같은 의미임. 전역 변수이기 때문에.
따라서 b값은 재할당가 동일하다고 보면 되므로 window.b가 대체함.

a는 다르지. let으로 변수로 만들고, 전역 변수로 또 window.a를 만들었다.

변수를 사용할때는 나랑 가까운 범위를 사용한다.
고로 더 가까운 let a를 사용하고 그리고 b는 둘다 전역변수이므로 재할당 된 window.b를 사용한다.

let a 의 값과 window.b의 값이 더해져서 5가 출력된다.



문제 5. 콘솔창에 1초에 한번씩 1부터 5까지의 정수를 출력해주고 싶습니다.

저번 연습문제에서 setTimeout이라는 유용한 함수를 배운 것 같습니다.

그래서 코드를 이렇게 작성했습니다.

setTimeout(function() { console.log(1); }, 1000 );
setTimeout(function() { console.log(2); }, 2000 );
setTimeout(function() { console.log(3); }, 3000 );
setTimeout(function() { console.log(4); }, 4000 );
setTimeout(function() { console.log(5); }, 5000 );
그럼 1초마다 1~5까지의 숫자를 콘솔창에 출력해줍니다.

하지만 반복되는 코드가 보기 싫어서 반복문 안에 담았습니다.

for (var i = 1; i < 6; i++) {
setTimeout(function() { console.log(i); }, i*1000 );
}
논리적으로 완벽한 for 반복문입니다.

그런데 반복문으로 축약하자마자 제대로 작동하지 않습니다.

계속 5라는 숫자가 1초마다 출력되네요.

Q. 위 코드는 왜 의도대로 동작하지 않는 것이죠? 설명해보십시오.

그리고 해결할 방법은 무엇일까요?

나의 답)
5가 아니라 6이 1초마다 나온다. 현재 for문에서 i를 var로 사용했는데, var는 범위가 함수 전체이기 때문에, setTimeout으로 출력하기 전 혼자서 계산을 다 끝내놓은 값을 console.log(i)에 던져주기 때문이다.

var는 이미 계산이 끝난 6이라는 값을 제공하고,
let은 이미 계산이 끝났더라도, 블록 스코프로 범위가 더 좁기 때문에 매번 새로운 i를 생성해서 던져주는데 이것이 1, 2, 3, 4, 5 를 제공한다.

var 대신 let으로 수정해주면 해결된다.



문제 6.버튼을 누르면 모달창을 띄우고 싶습니다.

버튼(button)과 모달창(div)가 3개 있습니다.

모달창0
모달창1
모달창2

버튼0
버튼1
버튼2

지금 display : none 덕분에 모달창이 아무것도 안보이는 상태입니다.

자바스크립트를 잘 짜서

0번째 버튼을 누르면 0번째 모달창,

1번째 버튼을 누르면 1번째 모달창을 보여주고 싶습니다.

그럼 코드를 어떻게 짜면 될까요?

여기까진 기본 자바스크립트 내용이니 친절히 알려드리겠습니다.

모달창0
모달창1
모달창2

버튼0
버튼1
버튼2

document.querySelectorAll은 jQuery의 $('') 셀렉터와 매우 유사합니다. 동시에 여러 요소를 찾아 어레이 비슷한 자료형에 담아줍니다.

아무튼 이렇게 쭉 쓰면

0번째 버튼을 누르면 0번째 모달창,

1번째 버튼을 누르면 1번째 모달창을 보여줍니다.

그런데 비슷한 코드들이 좀 보이죠? 이걸 반복문 안에 담아서 한번 다시 개발해보겠습니다.

두근두근

이렇게 반복문으로 반복적인 코드를 축약가능합니다.

그런데 문법에 맞게 쓰긴 했는데 모달창이 제대로 작동하지않고 있습니다.

Q. 위 코드는 왜 의도대로 동작하지 않는 것이죠? 설명해보십시오.

그리고 해결할 방법은 무엇일까요?

나의 답

이 문제에서도 var를 for문에서 사용하기 때문이다. 이로 인해 var i는 계산이 모두 되어버린 3이 되어버리고 계속 버튼들[3]과 모달창들[3]을 찾게 되어서 아래와 같은 오류를 일으킨다.

따라서 let을 이용하면 된다.

  <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>hi</h1>
  <div style="display : none">모달창0</div>
  <div style="display : none">모달창1</div>
  <div style="display : none">모달창2</div>

  <button>버튼0</button>
  <button>버튼1</button>
  <button>버튼2</button>

  <script>

    var 버튼들 = document.querySelectorAll('button');
    var 모달창들 = document.querySelectorAll('div');

    for (let i = 0; i < 3; i++){

      버튼들[i].addEventListener('click', function(){
        모달창들[i].style.display = 'block';
      });

    }
  </script>
</body>
</html>
profile
반드시 결승점을 통과하는 개발자

0개의 댓글