2021.05.14
기본적으로 좌클릭을 했을 때랑 우클릭을 했을 때를 나눠서 처리해야 한다.
1. 상태에 따른 코드 정의
2. 코드 작성 순서
3. Optional Chaining
4. nullish coalescing operator
5. Maximum call stack size exceeded 에러
상태값에 따른 코드를 정의할 때 보통 숫자로 지정하는데 여러 번 시뮬레이션을 한 뒤에 최적의 숫자조합을 찾는 것이 현명하다.
코드숫자는 0~8까지 열린 칸
지뢰가 없을 때 닫힌 칸(NORMAL)
은 -1, 물음표칸(QUESTION)
은 -2, 깃발 칸(FLAG)
은 -3.
지뢰가 있을 때 닫힌 칸은(MINE)
-4, 물음표칸(QUESTION_MINE)
은 -5, 깃발 칸(FLAG_MINE)
은 -6
candidate
에 빈 공간을 만들고 그 공간에 0부터 99까지 채워넣는다.chosen
배열에 mine
갯수인 10개를 뺀 공간에 랜덤으로 채워넣는다.rowData
배열에 CODE.NORMAL(-1)
을 채워넣는다.onRightClick
함수 생성 후 preventDefault
로 기본동작 제거. target
으로 html코드 불러올 수 있음.$tbody.addEventListener("contextmenu", onRightClick);
에서 contextmenu
는 우클릭이벤트인데 해당 이벤트 콜백을 onRightClick
으로 적용.onLeftClick()
을 선언 후 닫힌 칸인지 지뢰칸(지뢰칸이면 removeEventListener.
)인지 여부 판단 함.countMine()
도 정의해서 주변 지뢰갯수를 카운트한다.openAround(), isNormal(), open()
을 정의해서 open이 0
이면 openAround
가 주변을 열어준다.?.
.?
는 존재하지 않아도 괜찮은 대상에만 사용해야 한다.undefined
가 난다.(undefined[-1])
if (data[-1]) {
data[-1][-1];
}
이런 식으로 커버할 수 있으며, 또는 접근자 . 앞에 ?
를 붙이면 조건접근이 가능하다.
mines.includes(data[rowIndex - 1]?.[cellIndex - 1]) && i++;
obj?.prop;
obj?.[expr];
arr?.[index];
func?.(args);
nullish참조값
일 때 에러를 뱉고 ?.
연산자는 에러 대신 undefined
를 리턴하는 차이가 있다.let aProp = obj.first?.second;
obj.first.second
에 접근하기 전에 obj.first가 nullish가 아니라는 것을 암묵적으로 확인했다는 뜻
이다. 만약 obj.first가 nullish라면
그 표현식은 자동으로 잘리고 undefined가 반환
된다. 추가로 아래와 같이 풀어낼 수 있다. (참고:MDN)
let aProp =
obj.first === null || obj.first === undefined
? undefined
: obj.first.second;
??, ||, &&
를 추가로 설명하면 기존에 and, or처럼 판단을 해왔지만 엄밀히 논리적으로 따지면 아래와 같다.
A가 존재하지 않으면(false면) B.
존재하면(true면) A.
A가 Null 또는 Undefined면 B.
그 외엔 A.
A가 존재하면(true면) B.
존재하지 않으면(false면) A.
호출 스택
의 관점으로 봐야한다.
OnLeftClick()
위에 openAround()
가 여러 개가 얹어지면서 호출만 하고 끝나지 않는 상황이 발생하여 호출 스택
의 사이즈를 넘어가는 상황이 벌어진다.setTimeout()
) 백그라운드
와 태스크 큐
에 할당하면 된다.