이번에는 비동기라는 개념을 익히는 것이 중요하다.
const candidate = Array(45).fill().map((v, i) => i + 1);
const shuffle = [];
while (candidate.length > 0) {
const random = Math.floor(Math.random() * candidate.length); // 무작위 인덱스 뽑기
const spliceArray = candidate.splice(random, 1); // 뽑은 값은 배열에 들어 있음
const value = spliceArray[0]; // 배열에 들어 있는 값을 꺼내어
shuffle.push(value); // shuffle 배열에 넣기
}
console.log(shuffle);
slice와 splice 차이점
splice: 인덱스, 개수
slice: 인덱스, 인덱스
const winBalls = shuffle.slice(0, 6).sort((a, b) => a - b);
const bonus = shuffle[6];
console.log(winBalls, bonus);
setTimeout(() => {
//
}, 밀리초);
const $result = document.querySelector('#result');
const drawBall = (number, $parent) => {
const $ball = document.createElement('div');
$ball.className = 'ball';
$ball.textContent = number;
$parent.appendChild($ball);
};
변수는 스코프를 가지는데, var
는 함수 스코프를 가지고, let
은 블록 스코프를 가진다.
function b() {
var a = 1;
}
console.log(a);
> a is not defined
a를 콘솔로 출력하면 에러가 발생한다. a는 함수안에 선어된 변수이므로 함수 바깥에서 접근할 수 없다. 이렇듯 함수를 경계로 접근 경계가 달라지는 것을 함수 스코프라고 한다.
블록스코프는 변수의 접근 범위가 블록인 것이다. 블록은 함수, for, while, if 등을 포함하는데, let
과 const
는 블록 바깥에서 접근이 안된다.
var
는 블록 중에서 함수 바깥에서 접근이 안되는 것이다. 그래서 for, while, if 등등에서 let과 var가 차이가 난다.
if (true) {
var a = 1;
}
console.log(a);
>1
if는 함수가 아니기 때문에 접근이 가능하다.
if (true) {
let a = 1;
}
console.log(a);
> a is undefined
for (var i = 0; i < 5; i++) {}
console.log(i);
>5
var는 블록과 관계가 없어서 문제 없이 돌아간다. for문이 끝났을 때 i가 5가 되어있다.
let은 에러가 발생한다. for 문 바깥에서 접근했기 때문이다. 위치 상으로는 let이 블록 바깥에 있지만, for 문의 경우 블록 안에 있는 것으로 친다.
for (var i = 0; i < winBalls.length; i++) {
setTimeout(() => {
console.log(winBalls[i], i);
drawBall(winBalls[i], $result);
}, (i+1) * 1000);
}
for문은 동기인데 setTimeout부분은 비동기이다. for문이 빨리 돌아서 i를 6으로 만들어 버리는데, winBalls의 인덱스 6은 접근이 불가능하니 var로 하면 undefined가 나오는 것이다.
왜 let을 쓸 때는 문제가 되지 않았을까? 블록은 방어막 역할을 하는데, 바깥에서 접근하는 것을 막아주고, 안에 있는 것도 못나가는 역할을 해준다. let은 블록 스코프 안에서 고정이된다.
그렇다면 let이 나오기전 var로 어떻게 해결했을까? -> 클로저 (함수와 함수 바깥 변수와의 관계)
for (var i = 0; i < winBalls.length; i++) {
(function(j) {
setTimeout(() => {
console.log(winBalls[j], j);
drawBall(winBalls[j], $result);
}, (i+1) * 1000);
})(i);
}
i로 인자가 전달되고 그걸 j로 받는다. 그럼 j는 함수 안에 갇히게 된다.
function colorize(number, $tag) {
if (number < 10) {
$tag.style.backgroundColor = "red";
$tag.style.color = "white";
} else if (number < 20) {
$tag.style.backgroundColor = "orange";
} else if (number < 30) {
$tag.style.backgroundColor = "yellow";
} else if (number < 40) {
$tag.style.backgroundColor = "blue";
$tag.style.color = "white";
} else {
$tag.style.backgroundColor = "green";
$tag.style.color = "white";
}
}
숫자별로 배경색과 글자 색을 바꿔주는 것이다.