변수 연습문제 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
지금 display : none 덕분에 모달창이 아무것도 안보이는 상태입니다.
자바스크립트를 잘 짜서
0번째 버튼을 누르면 0번째 모달창,
1번째 버튼을 누르면 1번째 모달창을 보여주고 싶습니다.
그럼 코드를 어떻게 짜면 될까요?
여기까진 기본 자바스크립트 내용이니 친절히 알려드리겠습니다.
버튼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>