[자바스크립트] 인프런 - 렛츠기릿 자바스크립트 - 6강

June·2021년 7월 28일
0

로또 추첨기 순서도 그리기

이번에는 비동기라는 개념을 익히는 것이 중요하다.

공 뽑기(피셔 예이츠 셔플)

  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);

공 정렬하기(sort)

slice와 splice 차이점
splice: 인덱스, 개수
slice: 인덱스, 인덱스

  const winBalls = shuffle.slice(0, 6).sort((a, b) => a - b);
  const bonus = shuffle[6];
  console.log(winBalls, bonus);

일정 시간 후 실행하기(setTimeout)

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

변수는 스코프를 가지는데, var는 함수 스코프를 가지고, let은 블록 스코프를 가진다.

function b() {
  var a = 1;
}
console.log(a);
> a is not defined

a를 콘솔로 출력하면 에러가 발생한다. a는 함수안에 선어된 변수이므로 함수 바깥에서 접근할 수 없다. 이렇듯 함수를 경계로 접근 경계가 달라지는 것을 함수 스코프라고 한다.

블록스코프는 변수의 접근 범위가 블록인 것이다. 블록은 함수, for, while, if 등을 포함하는데, letconst는 블록 바깥에서 접근이 안된다.

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";
  }
}

숫자별로 배경색과 글자 색을 바꿔주는 것이다.

0개의 댓글