1~4. 다음 코드의 콘솔창 출력결과는 무엇일까요?
(문제1)
답은
함수는 잘 실행됩니다.
하지만 함수내부 코드가 이상합니다.
let 변수는 특이하게도 Hoisting이 되긴 하지만 undefined라는 값이 할당되지 않습니다.
그래서 출력시 에러를 뿜습니다.
let 변수는 hoisting 되지만 var 변수처럼 지동으로 undefined 라는 값을 할당(일명 initialization) 해주지 않습니다.
선언과 할당 사이에 시간차가 있기 때문에 그런 현상이 일어나는 것이고 let 변수는 그래서 쓸 수 없습니다
그래서 그냥 let const 변수는 그래서 엄격하게 쓸 수 있는 변수구나 외우시면 되겠습니다.
(문제2)
답은
이번에도 답은 에러입니다.
정확히 말하면 함수가 아닌데요? 라는 에러입니다.
지금 둘째줄에 있는 함수 선언부분을 잘 보시면 function 키워드 대신 변수만드는 것 처럼 함수를 선언과 할당하고 있습니다.
역시 이렇게 함수를 만드셔도 Hoisting이 되는데, 근데 Hoisting은 변수의 선언부분만 된다고 했었습니다.
그래서 변수 선언부분만 맨 위로 끌어올려지는데
그 변수에다가 소괄호를 붙여봤자 아직 함수가 아니기 때문에 실행이 되지 않습니다. (에러가 납니다. 함수가 아닌 변수에다가 소괄호 붙이면 함수 아니라고 에러를 뿜어줍니다.)
(문제3)
답은
a는 1이 출력됩니다.
a는 1이라는 변수를 만들고
그 다음에 함수를 만들고 함수 안에서 a = 2라고 값을 변경시켰는데
함수를 정의만 했지 실행을 안시켜서 a = 2라는 부분은 없는 코드나 마찬가지입니다.
그래서 a 는 그냥 1입니다.
(문제4)
a는 1, b는 4가 출력됩니다.
b가 4가 되는 이유는 var b = 2 이것과 window.b = 4 이건 거의 동일한 기능을 하는 코드기 때문에
b는 그냥 4로 재할당이 되었다고 보시면 되겠습니다.
a는 let 변수로 1을 할당하고 글로벌 변수로 3을 할당했습니다.
이 경우 우리가 a를 사용했을 때 조금 더 범위가 작고 가까운 1을 참조해서 사용합니다.
(자바스크립트 변수를 사용할 때 참조할만한 변수가 내 주변에 없으면 계속 상위 중괄호로 시선을 돌리면서 참조합니다.)
5. 콘솔창에 1초에 한번씩 1부터 5까지의 정수를 출력해주고 싶습니다.
논리적으로 완벽한 for문입니다.
그런데 반복문으로 축약하자마자 제대로 작동하지 않습니다.
계속 5라는 숫자가 1초마다 출력되는모습을 볼 수 있습니다.
Q.why?
답은
자바스크립트는 일단 반복문을 만나면 반복문 내의 코드를 반복해서 실행합니다.
지금 반복문이 i가 0부터 5가 되기 전까지 반복해주세요~라고 써놓았으니 총 5번 반복이 되겠네요.
근데 내부 코드는 setTimeout 어쩌구 입니다. X초후에 콜백함수 내의 console.log(i)를 실행해주세요~ 라는 코드입니다.
그래서 그 부분은 반복문과 동시에 실행되지 않습니다. 좀 나중에 실행되겠죠 뭐.
반복문 끝입니다.
반복문을 해석한 후.. 1초가 지나면 setTimeout 내의 console.log(i)가 발동됩니다.
근데 i를 채워넣고싶어서 주변을 살펴보았더니 i값은 5밖에 없는 것입니다.
왜냐면 아까 반복문이 5번 실행되면서 i값은 0,1,2,3 ... 이렇게 차례로 변하다가 i값이 5가 되어 종료했습니다.
그리고 i 값은 var로 만든 전역변수입니다.
그래서 i값을 쓰려고 봤더니 전역변수 i = 5밖에 없어서 5를 집어넣어서 계속 실행해서 콘솔창에 5가 계속 출력되던 것입니다.
var의 범위는 함수 스코프(function scope)이니까 말이죠
해결책은 for 반복문에서 i변수를 만들 때 var 대신 let으로 바꾸는 것입니다.
let 변수는 범위가 중괄호 즉, 블록 스코프(block scope)이므로 for반복문도 중괄호에 해당됩니다.
그럼 이제 1초 후 console.log(i)가 실행될 때 i값을 채우려고 살펴보면
i값이 for 반복문 내에 남아있기 때문에 그걸 가져다 쓰게 됩니다.
그래서 아까처럼 계속 5를 출력해주는게 아니라 0,1,2,3,4를 출력해줍니다.
6. 버튼을 누르면 모달창을 띄우고 싶습니다.
버튼(button)과 모달창(div)가 3개 있습니다.
지금 display : none 덕분에 모달창이 아무것도 안보이는 상태입니다.
자바스크립트를 잘 짜서
0번째 버튼을 누르면 0번째 모달창,
1번째 버튼을 누르면 1번째 모달창을 보여주고 싶습니다.
그럼 코드를 어떻게 짜면 될까요?
document.querySelectorAll은 jQuery의 $('') 셀렉터와 매우 유사합니다. 동시에 여러 요소를 찾아 어레이 비슷한 자료형에 담아줍니다.
아무튼 이렇게 쭉 쓰면
0번째 버튼을 누르면 0번째 모달창,
1번째 버튼을 누르면 1번째 모달창을 보여줍니다.
그런데 비슷한 코드들이 좀 보이죠? 이걸 반복문 안에 담아서 한번 다시 개발해보겠습니다.
이렇게 반복문으로 반복적인 코드를 축약가능합니다.
그런데 문법에 맞게 쓰긴 했는데 모달창이 제대로 작동하지않고 있습니다.
Q. 위 코드는 왜 의도대로 동작하지 않는 것이죠? 해결할 방법은 무엇일까요?
답은
방금 전 문제랑 거의 똑같은 경우의 문제입니다.
자바스크립트 입장에서 하단 코드를 해석해보겠습니다.
자바스크립트는 일단 반복문을 만나면 반복문 내의 코드를 반복해서 실행합니다.
지금 반복문이 i가 0부터 3이 되기 전까지 반복해주세요~라고 써놓았으니 총 3번 반복이 되겠네요.
근데 내부 코드는 addEventListener 어쩌구 입니다. 클릭 되면 콜백함수 내의 모달창들[i].style.display = 'block'; 을 실행해주세요~ 라는 코드입니다.
그래서 그 부분은 반복문과 동시에 실행되지 않습니다. 좀 나중에 클릭 되면 실행되겠죠 뭐.
반복문 끝입니다.
반복문을 해석한 후.. 누군가 버튼을 클릭하면 addEventListener 내의 모달창들[i].style.display = 'block'; 코드가 발동됩니다.
근데 i를 쓰고싶어서 주변을 살펴보았더니 i값은 3밖에 없는 것입니다.
왜냐면 아까 반복문이 3번 실행되면서 i값은 0,1,2,3 ... 이렇게 차례로 변하다가 i값이 3이 되어 종료했습니다.
그리고 i 값은 var로 만든 전역변수입니다.
그래서 i값을 쓰려고 봤더니 전역변수 i = 3밖에 없어서 3을 집어넣어서 계속 에러가 났던 것입니다.
해결책은 for 반복문에서 i변수를 만들 때 var 대신 let으로 바꾸는 것입니다.
let 변수는 범위가 중괄호랬죠? for반복문도 중괄호에 해당됩니다.
반복문이 돌고 나서도 let i = 어쩌구 값이 {for 반복문} 내에 남아있기 때문에 그걸 모달창들[i].style.display = 'block'; 의 i값으로 가져다 쓰게 됩니다.
그럼 이제 의도된 i값으로 코드가 잘 실행됩니다.
출처 : 코딩애플의 매우쉽게 이해하는 JavaScript 객체지향 & ES6 신문법
'JavaScript > ES6' 카테고리의 다른 글
[ES6]Spread Operator 2. & apply, call함수 (0) | 2022.08.24 |
---|---|
[ES6]Spread Operator 1. (0) | 2022.08.24 |
[ES6]Template literals/Tagged literals (0) | 2022.08.24 |
[ES6]Arrow function (0) | 2022.08.24 |
[ES6]this (0) | 2022.08.24 |