-window.crypto.getRandomValues() : 랜덤한 숫자를 뽑아내는 함수. Math.random()은 보안상의 위험이 있고 완전한 랜덤이 아니기 때문에 이 함수를 사용하는 경우가 있음 -new Set(배열)을 이용하여 배열속에 중복을 제거할 수 있음 -new Set(배열).size : 중복이 제거된 배열의 길이를 알 수 있음(요소의 종류) -alert()는 undefined이므로 if의 조건문 안에 들어가면 false가 된다.
-배열.join('구분할문자열') : 배열을 문자열로 바꾸되, 구분할 문자열을 사이에 집어넣는다(없을경우 비우면됨) -문자열.split('구분할문자열') : 문자열을 배열로 바꾸되, 구분할문자열을 기준으로 요소를 쪼개서 배열로 바꿈(''를 넣을시 한글자씩 쪼갬) -'\n' : 자바스크립트에서의 문자열 줄바꿈코드 -아니면 innerHTML에 <br/>코드를 넣어주면 줄바꿈이 됨
-appendChild는 요소를 CreatetextNode를 한 후에 해야하는데, append는 바로가능
-배열.slice(0,3) : 첫번째(0)부터 네번째 전까지(3)를 잘라낸후 반환. 원래 배열은 바뀌지 않음 *배열.slice(4, -1) : index4부터 index-1(뒤에서 첫번째 전) 까지 *배열.slice(4) : index4부터 끝까지 *배열.slice(-5, -1) : index-5(뒤에서 5번째)부터 index-1(뒤에서 첫번째)전까지 *배열.slice() : 원본을 복사함 (.sort와 같이 원본 배열을 변경하는 함수를 사용하고 원본을 유지하기 위해 사용) *배열.slice().sort(() => {}) : 원본배열은 유지된채로 정렬된 배열을 새로 만들 수 있음
*for문에 var로 변수를 지정하면 winBalls[i],i가 undefined,6로 출력되면서 제대로 동작하지 않게됨. 이는 for문이 동기적 실행, setTimeout이 비동기적 실행을 해서 그렇다. var는 함수스코프이기때문에 전역변수로 다뤄져 for문이 6번동기적실행을 할때 이미 i가 6이되버린다. 그리고 시간이 지난후 setTimeout이 작동 하면서 비동기적으로 6번을 반복해서 실행하는데, 이때 이미 i가 6이므로 winBalls[6]은 undefined를 출력하고, i는 6이된다. 따라서 프로그램이 망가짐. *var는 웬만하면 쓰지말고, 오래된 코드를 볼때 동작원리를 파악하기 위해서만 알아두는 지식이다.
for (leti=0; i<winBalls.length; i++){
setTimeout(() => {
showBalls(winBalls[i], $result);
}, (i+1)*1000);
}
그러면 let은 왜 잘실행되는가? let은 블록스코프이기떄문에 i값이 for문을 돌면서 고정되기 때문에 오류가 나지 않음 let으로 설정햇기때문에 i값이 밖으로 나가지 못하고 안에서 고정되어 반복문을 돌면서 i의 값이 순차적으로 고정됨
-var를 이용해서 정상적으로 실행하고 싶다면 다음과같이 작성하면 됨 (클로저문제-비동기함수와 함수스코프var가 만나면 생기는 문제)
-객체리터럴 A[]와 A.~~의 사용법 *A[]는 []안에 변수를 넣을 수 있음. A[변수]로 사용. *A["문자열"] = A.문자열과 동일하며 A안의 문자열 키를 찾아 값을 반환함
constrspX = {
scissors :'0',
rock :'-220px',
papper :'-440px',
}
letcomputerChoice = 'scissors';
-위의 경우 rspX.scissors = rspX["scissors"]와 같음. -하지만 rspX.computerChoice를 하면 문자열 computerChoice가 객체리터럴 안의 키값으로 존재하지 않으므로 undefined를 반환함. -변수를 이용해 객체리터럴의 값을 반환하기 위해서는 rspX[computerChoice]라고 입력해야함.
-clearTimeout(setTimeout을 담은 변수) : timeout이 실행되기 전에 timeout을 멈출 수 있음. -clearInterval(setInterval을 담은 변수) : interval을 멈출수 있음
-가위바위보에서 버튼을 연속클릭함으로써 손이 빨라지고 버튼을 눌러도 안멈추는 버그
letintervalId = setInterval(changeComputerHand, 50); //clearInterval을 하기 위해 setInterval의 반환값을 받는 코드
constclickButton = () => { //버튼을 눌렀을때 잠시 멈췄다가 다시 실행하는 코드
clearInterval(intervalId);
setTimeout(() => {
intervalId = setInterval(changeComputerHand, 50) //setInterval반환값이 그때그때 달라지기 때문에 다시 넣어주는것
}, 1000);
}
$rock.addEventListener("click", clickButton);
$scissors.addEventListener("click", clickButton);
$papper.addEventListener("click", clickButton);
원인 : 2번 연속으로 클릭했을때, 1번째 클릭하면 원래돌아가던 인터벌은 멈추고 1초이후에 1번인터벌이 시작됨. 하지만 1초전에 한번더 버튼을 클릭하면 1번째 클릭한 인터벌이 시작하기도 전에 clearInterval을 함으로써 1번인터벌이 안지워진채로 2번인터벌이 새로등록되고 1번인터벌의 intervalId값이 지워지고 2번인터벌의 id값이 저장됨. 그래서 1번인터벌과 2번인터벌이 동시에 돌아가면서 손이 아주 빠르게 작동하는것. 이 경우에 2번인터벌이후 3번인터벌을 등록하더라도 2번인터벌은 지워져도 1번인터벌은 계속 돌아가므로 버튼을 눌러도 손이 안멈추는것.
해결책1 : settimeout이 실생되기 직전에 다시 인터벌을 지운다
constclickButton = () => {
clearInterval(intervalId);
setTimeout(() => {
clearInterval(intervalId); //여러번누르더라도 interval이 새로등록되기 직전에 직전의 인터벌을 지움으로써 하나의 인터벌만 실행되게 만듬.
intervalId = setInterval(changeComputerHand, 50)
}, 1000);
}
해결책2 : removeEventListener를 이용해서 버튼을 클릭했을때 이벤트를 지우고, settimeout을 이용해 시간이 지난후 이벤트를 다시 추가한다