책 You Don't Know JavaScript Yet의 부록에 있는 연습 문제를 풀어본 내용을 정리하였습니다.
함께 소개된 모범 답안은 굳이 옮겨 놓지 않았으나 상세한 내용은 원문 Repository에 있는 "Suggested Solutions"에서 확인할 수 있습니다.
① 함수 scheduleMeeting()은 "hh:mm"형태(24시간을 기준으로 시간을 나타내는 문자열)로 된 2가지 인수를 받는다.
startTime: 회의 시작 시간durationMinutes: 분 단위의 회의 지속 시간② 변수 dayStart와 dayEnd에는 근무 종료 시간이 할당된다.
③ 함수는 회의가 근무 시간 내에 이뤄질 경우 true를, 그렇지 않으면 false를 반환한다.
const dayStart = "07:30";
const dayEnd = "17:45";
function scheduleMeeting(startTime,durationMinutes) {
// ..TODO..
}
scheduleMeeting("7:00",15); // false
scheduleMeeting("07:15",30); // false
scheduleMeeting("7:30",30); // true
scheduleMeeting("11:30",60); // true
scheduleMeeting("17:00",45); // true
scheduleMeeting("17:30",30); // false
scheduleMeeting("18:00",15); // false
const dayStart = "07:30";
const dayEnd = "17:45";
const now = Date.now();
const dayStartTime = timeStrToDate(dayStart);
const dayEndTime = timeStrToDate(dayEnd);
function timeStrToDate(timeStr) {
if (typeof timeStr !== "string") return timeStr;
const [hours, minutes] = timeStr.split(':').map(Number);
return new Date(now).setHours(hours, minutes, 0, 0);
}
function scheduleMeeting(startTime, durationMinutes) {
const sTime = timeStrToDate(startTime);
const eTime = sTime + (1000 * 60 * durationMinutes);
return sTime >= dayStartTime && eTime <= dayEndTime;
}
timeStrToDate() 함수를 별도로 정의하여, 시간을 나타내는 문자열을 Date 객체로 변환하도록 했다.Date.now())를 기준으로 setHours() 메서드를 사용해 시간만 다르게 설정해 주었다.sTime) 및 종료 시간(eTime)은 모두 Date() 생성자를 통해 만들어진 객체로써 밀리초 단위의 UNIX 타임스탬프 값을 가지고 있다.① 함수 range()는 2개의 숫자로 된 인자를 받으며, 각 숫자는 원하는 범위의 시작과 끝을 나타낸다.
② 2번째 인자가 없는 경우에는 2번째 인자를 넘길 수 있도록 하는 함수가 반환되어야 한다.
function range(start, end) {
// ..TODO..
}
range(3, 3); // [3]
range(3, 8); // [3, 4, 5, 6, 7, 8]
range(3, 0); // []
var start3 = range(3);
var starrt4 = range(4);
start3(3); // [3]
start3(8); // [3, 4, 5, 6, 7, 8]
start3(0); // []
start4(6); // [4, 5, 6]
function range(start, end) {
if (end !== undefined) {
return generateRange(start, end);
}
return function(last) {
return generateRange(start, last);
}
}
function generateRange(start, end) {
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
}
range()는 인자에 따른 처리와 클로저 생성을 담당한다.end가 전달된 경우, 즉시 범위를 생성해 반환한다.end가 전달되지 않은 경우, 클로저를 반환한다.start로 미리 설정해 뒀다가 start는 내부 상태로써 계속 유지되며, generateRange()를 별도로 정의하여 재사용 하도록 만들었다. (실제 범위 생성 담당)① 독립적으로 돌아가는 릴 3개가 있는 슬롯머신이 있다.
spin() 실행: 3개의 릴이 돌아간다.display() 실행: 결과가 출력된다.② 릴 하나의 동작은 reel 객체에 정의되어 있다. 슬롯머신에는 여러 개의 릴이 있으므로 각 릴은 해당 객체를 상속받아야 한다. 추가로 릴에는 position 프로퍼티도 필요하다.
③ 일반적으로 슬롯머신의 릴은 결과에 해당하는 심볼 하나(position)와 앞 심볼(position-1), 뒷 심볼(position+1)를 함께 표시한다. 따라서 display()를 실행하면 3x3 그리드에 총 9개의 기호가 출력되어야 한다.
🪄 힌트 )
%)를 사용하면 릴을 원형으로 만들 수 있다.Object.create()로 프로토타입이 있는 객체를 만들어라. 프로토타입 연결이 만들어지면 위임 덕분에 상속 객체들은 메서드 호출 시 this 컨텍스트를 공유하게 된다.position을 보여주기 위해 객체 reel을 직접 수정하는 대신, 다시 Object.create()를 사용해서 임시 객체를 하나 만들고, 여기에서 위임을 통해 position을 관리하라.function randMax(max) {
return Math.trunc(1E9 * Math.random()) % max;
}
var reel = {
symbols: [
"♠", "♥", "♦", "♣", "☺", "★", "☾", "☀"
],
spin() {
if (this.position == null) {
this.position = randMax(
this.symbols.length - 1
);
}
this.position = (
this.position + 100 + randMax(100)
) % this.symbols.length;
},
display() {
if (this.position == null) {
this.position = randMax(
this.symbols.length - 1
);
}
return this.symbols[this.position];
}
};
var slotMachine = {
reels: [
// ..TODO..
// 슬롯머신에는 3개의 릴이 필요하다
// 힌트: Object.create(..)
],
spin() {
this.reels.forEach(function spinReel(reel){
reel.spin();
});
},
display() {
// ..TODO..
}
};
slotMachine.spin();
slotMachine.display();
// ☾ | ☀ | ★
// ☀ | ♠ | ☾
// ♠ | ♥ | ☀
slotMachine.spin();
slotMachine.display();
// ♦ | ♠ | ♣
// ♣ | ♥ | ☺
// ☺ | ♦ | ★
var slotMachine = {
reels: [
Object.create(reel),
Object.create(reel),
Object.create(reel)
],
spin() {
this.reels.forEach(function spinReel(reel){
reel.spin();
});
},
display() {
const lines = [];
for (let i = -1; i <= 1; i++) {
const line = this.reels.map(function generateLine(reel) {
const slot = Object.create(reel);
slot.position = (
reel.symbols.length + reel.position + i
) % reel.symbols.length;
return slot.display();
});
lines.push(line.join(' | '));
}
return lines.join('\n');
}
};
slotMachine.reels는 3개의 릴을 가진 슬롯 머신을 의미한다.slotMachine.display()는 3개의 릴을 가진 슬롯 머신의 현재 상태를 표시한다.reel 객체의 프로토타입을 상속받도록 해 display()를 호출할 수 있다.position은 순환 구조(마지막 심볼 다음에 첫 번째 심볼을 가르키도록)를 따르므로, 나머지 연산을 활용하였다. postion이 순서대로 4, 3, 7 이라고 가정하면lines[0] 에는 순서대로 3, 2, 6 번째 심볼을 표시해 현재 릴의 이전 위치를 나타내며lines[1] 에는 순서대로 4, 3, 7 번째 심볼을 표시해 현재 릴의 위치를 나타내고lines[2] 에는 순서대로 5, 4, 0 번째 심볼을 표시해 현재 릴의 다음 위치를 나타낸다.