1. 비동기 - 코드 순서대로 실행되지 않고 특정한 동작을 했을 때 실행되는 행위. 동기의 반대
2. sort
- 정렬하는 함수, 숫자 나 문자도 정렬됨.
const array = [1, 4, 3, 8, 5, 9, 7];
// 오름차순으로 정렬되지만 원본이 훼손됨.
array.sort((a, b) => {
return a - b
})
// 내림차순으로 정렬
array.sort(
(a, b) => {
return b - a
})
// slice()를 사용해서 복사한다. 원본을 훼손하지 않는다.
array.slice().sort((a, b) => {
return a - b
});
//문자열 첫번째글자의 코드넘버를 비교해서 정렬한다.
const fruitsarray = ['apple', 'banana', 'kiwi', 'orange', 'grape'];
fruitsarray.slice().sort((a, b) => a[0].charCodeAt() - b[0].charCodeAt())
// ['apple', 'banana', 'grape', 'kiwi', 'orange']
//문자열정
fruitsarray.slice().sort((a, b) => a.localeCompare(b))
3. setTimeout()
- 자바스크립트의 타이머의 시간은 정확하지 않다. 기본적으로 자바스크립트는 한 번에 한가지 일만 할수 있다. 이미 많은 일을 하고 있다면 설정한 시간이 되어도 setTimeout에 지정된 작업이 수행되지않는다. 기존에 하고 있던 일이 끝나야 setTimeout에 지정한 작업이 실행된다.
setTimeout(() => {
//특정시간후에 실행될 함수
}, 밀리초) // 밀리초 : 천분의일
setTimeout(() => {
func()
}, 8000)
setTimeout(func,8000)
4. var 와 let 의 차이
var - 함수 스코프(함수만 신경쓴다.)
let -블록 스코프 (if,switch,for 등)
if (true) {
var a = 1;
}
console.log(a);
//1
if (true) {
let b = 1;
}
console.log(b);
// 블록 스코프라서 if문밖에서 접근안됨
Uncaught ReferenceError ReferenceError: b is not defined
- var는 블록과 관계없이 돌아간다. for문이 끝났을 때 i 가 5가 되어있다.
for (var i = 0; i < 5; i++) {}
console.log(i);
//5
for (let j = 0; j < 5; j++) {}
console.log(j);
Uncaught ReferenceError ReferenceError: j is not defined
- 비동기와 var(함수 스코프)가 만나면 클로저 문제가 발생
for (var i = 0; i < 6; i++) {
let time = (i + 1) * 1000;
setTimeout( () => {
showball(i, 'result');
}, time)
}
-형광색친 부분(콜백함수) 안에 든 i와 바깥의 time 은 다른 시점에서 실행됨.
Time은 반복문을 돌 때 실행되고 setTimeout 의 콜백함수는 지정한 시간 뒤에 호출함. 그런데 반복문은 빠른 속도로 돌기때문에 콜백 함수가 실행 될때는 이미 i가 6이 되어있다.
}
클로저를 사용해서 문제해결함.
for (var i = 0; i < 6; i++) {
let time = (i + 1) * 1000;
(function(j) {
setTimeout(() => {
showball(i, 'result');
}, time);
})(i);
}
이러한 문제 떄문에 let 을 사용함
5. 로또추점기 전체 코드
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>로또추첨기</title>
<style>
.ball {
display: inline-block;
border: 1px solid black;
border-radius: 20px;
width: 40px;
height: 40px;
line-height: 40px;
font-size: 20px;
text-align: center;
margin-right: 20px;
}
</style>
</head>
<body>
<div id="result">추첨 결과는? </div>
<div id="bonus">보너스: </div>
<script>
const candidate = Array(45).fill(0).map((el, index) => {
return index + 1;
}); // 45개
// 램덤으로 candidat배열을 섞고 난 후에 앞에서 7개만가져온다.
// 피셔-예이츠 셔플 알고리즘 이용
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);
}
const winBalls = shuffle.slice(0, 6).sort((a, b) => a - b);
const bonus = shuffle[6];
const $result = document.querySelector("#result");
const $bonus = document.querySelector("#bonus");
const showball = (number, $target) => {
const $ball = document.createElement('div');
$ball.className = 'ball';
$ball.textContent = winBalls[number];
console.log($target)
if ($target == 'result') {
$result.appendChild($ball);
}
}
for (let i = 0; i < 6; i++) {
let time = (i + 1) * 1000;
setTimeout(() => {
showball(i, 'result');
}, time)
}
for (let i = 0; i < 6; i++) {
let time = (i + 1) * 1000;
setTimeout(() => {
showball(i, 'result');
}, time)
}
setTimeout(() => {
const $ball = document.createElement('div');
$ball.className = 'ball';
$ball.textContent = bonus;
$bonus.appendChild($ball);
}, 8000)
</script>
</body>