과거 프로그래밍 자료들/Javascript&typescript
[호출스택]실행하지 않고 함수에서 변수로 접근 가능한지 알기
평부
2022. 9. 8. 14:30
* 참고한 강의
https://www.youtube.com/watch?v=-79WfViYw3k&list=PLcqDmjxt30Rt9wmSlw1u6sBYr-aZmpNB3&index=2https://www.youtube.com/watch?v=ZF6aDhBp5r8&list=PLcqDmjxt30Rt9wmSlw1u6sBYr-aZmpNB3&index=3
호출스택
* 호출스택
- 프로그램 상에서 우리가 어떤 순서로 작업을 수행하는 지 기록하는 지 기록하는 작업 스케줄링과 관련된 자료
[예제 1]
const x = "x";
//선언
function c() {
const y = "y";
console.log("c");
//debugger
}
//선언
function a() {
const x = "x";
console.log("a");
function b() {
console.log("b");
c(); //호출
}
b();
}
a();
c();
* 결과
- a(); : a, b, c
- c(); : c
* 호출스택 예시(카드 짝 맞추기 게임)
https://thebook.io/080270/part02/ch11/05/01-02/
[예제 2]
- 코드 길어서 "더보기" 누르면 볼 수 있음
더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>짝맞추기</title>
<style>
.card {
display: inline-block;
margin-right: 20px;
margin-bottom: 20px;
width: 70px;
height: 100px;
perspective: 140px;
}
.card-inner {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.card.flipped .card-inner {
transform: rotateY(180deg);
}
.card-front {
background: navy;
}
.card-front,
.card-back {
position: absolute;
width: 100%;
height: 100%;
border: 1px solid black;
backface-visibility: hidden;
}
.card-back {
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div id="wrapper"></div>
<script>
const $wrapper = document.querySelector('#wrapper');
const total = parseInt(prompt('카드 개수를 짝수로 입력하세요(최대 20).'));
const colors = [
'red', 'orange', 'yellow', 'green', 'white',
'pink', 'cyan', 'violet', 'gray', 'black',
];
let colorSlice = colors.slice(0, total / 2);
let colorCopy = colorSlice.concat(colorSlice);
let shuffled = [];
let clicked = [];
let completed = [];
let clickable = false;
let startTime;
function shuffle() { // 피셔-예이츠 셔플
for (let i = 0; colorCopy.length > 0; i += 1) {
const randomIndex = Math.floor(Math.random() * colorCopy.length);
shuffled = shuffled.concat(colorCopy.splice(randomIndex, 1));
}
}
function createCard(i) { // div.card > div.card-inner > (div.card-front + div.card-back)
const card = document.createElement('div');
card.className = 'card'; // .card 태그 생성
const cardInner = document.createElement('div');
cardInner.className = 'card-inner'; // .card-inner 태그 생성
const cardFront = document.createElement('div');
cardFront.className = 'card-front'; // .card-front 태그 생성
const cardBack = document.createElement('div');
cardBack.className = 'card-back'; // .card-back 태그 생성
cardBack.style.backgroundColor = shuffled[i];
cardInner.appendChild(cardFront);
cardInner.appendChild(cardBack);
card.appendChild(cardInner);
return card;
}
// clicked : [2, 5, 8, 9]
// 태스크큐:
// 백: addEventListener(12),
function onClickCard() {
if (!clickable || completed.includes(this) || clicked[0] === this) {
return;
}
this.classList.toggle('flipped');
clicked.push(this);
if (clicked.length !== 2) {
return;
}
const firstBackColor = clicked[0].querySelector('.card-back').style.backgroundColor;
const secondBackColor = clicked[1].querySelector('.card-back').style.backgroundColor;
if (firstBackColor === secondBackColor) { // 두 카드가 같은 카드면
completed.push(clicked[0]);
completed.push(clicked[1]);
clicked = [];
if (completed.length !== total) {
return;
}
const endTime = new Date();
setTimeout(() => {
alert(`축하합니다! ${(endTime - startTime) / 1000}초 걸렸습니다.`);
resetGame();
}, 1000);
return;
}
clickable = false;
setTimeout(() => {
clicked[0].classList.remove('flipped');
clicked[1].classList.remove('flipped');
clicked = [];
clickable = true;
}, 500);
}
function resetGame() {
$wrapper.innerHTML = '';
colorCopy = colors.concat(colors);
shuffled = [];
completed = [];
startGame();
}
function startGame() {
clickable = false;
shuffle();
for (let i = 0; i < total; i += 1) {
const card = createCard(i);
card.addEventListener('click', onClickCard);
$wrapper.appendChild(card);
}
document.querySelectorAll('.card').forEach((card, index) => { // 초반 카드 공개
setTimeout(() => {
card.classList.add('flipped');
}, 1000 + 100 * index);
});
setTimeout(() => { // 카드 감추기
document.querySelectorAll('.card').forEach((card) => {
card.classList.remove('flipped');
});
clickable = true;
startTime = new Date();
}, 5000);
}
startGame();
</script>