값 VS 참조
값의 타입에 따라 값 자체를 넘겨줄지, 값의 참조를 넘겨줄지 결정된다. > JS의 작동방식. 바꿀수없다
원시타입=값이 복사되어 전달됨. var myName="Amy" var yourName = myName (myName을 바꿔도 yourName은 안바뀜)
객체타입=값의 참조(주소)를 복사해 전달. 여러 변수가 하나의 공유값을 가리킴. 공유값을 수정하면 참조하는 모든변수가 바뀜
다양한 형태의 함수
익명함수표현식
var nonameF = function () {...} > 이때는 익명함수더라도 자체적으로 이름을 추론하기 때문에 nonameF.name = nonameF 그러나 인수로 전달시에는 name은 빈문자열, anonymous function으로 콘솔찍힘.
기명함수표현식
var nameF = function exName() {..} > 런타임시 식별자nameF와 연관. 직접 지정한 함수이름exName이 우선순위.
둘중 어떤 방식을 쓸까? 대부분이 익명함수표현식 사용함. 짧고 일반적이라. (필자왈-기명함수를 선호) 프로그램내 함수는 목적이 있어야하고, 목적을 설명하는 이름을 부여해야함. 그러면 굳이 이름을 추론할 필요없다.
여러가지 함수선언방식을 충분히 숙지하고 연습하자
제너레이터 - function *two() {}
async함수- async function three(){}
async제너레이터 함수 - async function *four(){}
IIFE(즉시실행함수) 표현식 - (function(){..})()
비동기 IIFE - (async function() {})()
화살표함수표현식 - var f =(x)=>x*2
화살표함수는 익명이다.(문법적으로) 특별한목적을 가진 함수(this가 참조하는 렉시컬환경 핸들링하기)
클래스메서드는 쉼표가 없다, 객체메서드는 쉼표로 구분함.
강제 조건부 비교
비교전 무조건 강제변환이 일어난다. Boolean() 타입으로.
var x = "안녕하세요";
if (x == true) {
console.log("괄호실행"); //실행되지 않음!! Boolean(x)는 true인데 왜?
}
(+추가) == 연산자는 양쪽 값을 비교하기 전에 암묵적인 형 변환을 수행함. x를 숫자로 변환하려고 시도하지만 NaN. 따라서 NaN!==true이므로 실행안됨.,
해결책은 Boolean(x)나 if (x)를 사용하면 됩니다. 이렇게 하면 x가 빈 문자열이 아닌 이상 true로 평가되어 if문이 실행됩니다.
프로토타입 클래스
프로토타입을 사용한 상속, 모든함수는 기본적으로 prototype프로퍼티를 가지고 빈 객체를 참조함.
(프로토타입 프로퍼티 != 함수의 프로토타입과 다름)
프로토타입 프로퍼티는 new로 호출해 객체를 만들때, 새롭게 만든 객체의 프로토타입을 설정할수 있게해줌
프로토타입 클래스패턴 VS ES6 클래스 매커니즘? 클래스지향 디자인패턴은 ES6 클래스가 적합.
B1.비교 연습하기
처음시도한 방법 : 냅다 문자열비교하기 startHour >= dayStart && startHour <= dayEnd
문제 : 07:30 == 7:30 비교시 false 나옴..
수정한 방법 : 문자열을 숫자로 바꿔서 비교하자.
(방법1) Number(startHour) 로 변환하기 ...는 NaN이 나와서 안됨
(방법2) 콜론 기준 split해서 각각 hour, minute을 Number로 변환하기.
최종코드
const dayStart = "07:30"; // 근무시작시간
const dayEnd = "17:45"; //근무종료시간
//console.log(5 + dayEnd); //517:45 문자열로 바꿔버림
//console.log(Number(dayEnd)); //NaN
//회의가 근무시간내 이뤄지면 true, 아니면 false
function scheduleMeeting(startTime, duartionMinutes) {
let [dayStartHour, dayStartMinute] = dayStart.split(":").map(Number);
let [dayEndHour, dayEndMinute] = dayEnd.split(":").map(Number);
let [startHour, startMinute] = startTime.split(":").map(Number);
if (
(startHour >= dayStartHour && startMinute >= dayStartMinute) ||
(dayStartHour < startHour &&
startHour <= dayEndHour &&
startMinute <= dayEndMinute) //여기서 dayStartHour < startHour 조건을 넣지않으면 07:00 을 테스트했을때 true나옴!
) {
//시작시간이 근무시간 중이면, 끝나는 시간도 고려해야함
let endHour = startHour;
let endMinute = startMinute + duartionMinutes; //끝나는 시간 계산중
if (endMinute >= 60) {
endHour += 1;
endMinute = endMinute - 60;
}
if (endHour < 17 || (endHour <= 17 && endMinute <= 45)) {
//회의끝난시간이 퇴근전이면 true
return true;
} else return false; //아니면 false
}
// 시작시간이 근무시간 중이 아니면 false
return false;
}
console.log(scheduleMeeting("7:00", 15));
console.log(scheduleMeeting("07:15", 30));
console.log(scheduleMeeting("7:30", 30));
console.log(scheduleMeeting("11:30", 60));
console.log(scheduleMeeting("17:00", 45));
console.log(scheduleMeeting("17:30", 30));
console.log(scheduleMeeting("18:00", 15));
B2.클로저 연습하기
function range(start, end) {
if (end == undefined) {
return function (end) {
let ret = [];
for (let i = start; i <= end; i++) {
ret.push(i);
}
return ret;
};
}
let ret = [];
for (let i = start; i <= end; i++) {
ret.push(i);
}
return ret;
}
console.log(range(3, 3));
console.log(range(3, 8));
console.log(range(3, 0));
var start3 = range(3);
var start4 = range(4);
console.log(start3(3));
console.log(start3(8));
console.log(start3(0));
console.log(start4(6));
B3.프로토타입 연습하기
1e9 은 무엇인가? 정수형으로 10억
Math.floor 내림, Math.trunc 버림.
- Math.trunc(): 소수점 이하를 무조건 버림.
- Math.floor(): 소수점을 버리고 작은 쪽으로 내림.
function randMax(max) {
return Math.trunc(1e9 * Math.random()) % max; //0~max-1 까지의 무작위 수 생성
}
var reel = {
//reel객체, reel동작을 정의
symbols: [
//symbols.length = 8
"\u2660", //스페이드
"\u2665", //하트
"\u2666", //다이아
"\u2663", //클로버
"\u263A", //스마일
"\u2605", //별
"\u2764", //달**이모지깨져서 바꿈..원래 \u1F319
"\u2600", //해
],
spin() {
if (this.position == null) {
//맨처음에만 실행됨, position을 0~6까지로 설정함 (**수정필요)
this.position = randMax(this.symbols.length - 1); //**여기가 this.symbols.length여야함 그래야 0~7까지나옴
} //두번째부터는 아래코드 실행됨
this.position = (this.position + 100 + randMax(100)) % this.symbols.length;
},
display() {
if (this.position == null) {
// position을 0~6까지로 설정함 (**수정필요)
this.position = randMax(this.symbols.length - 1);
}
return this.symbols[this.position]; //position에 해당하는 심볼기호를 리턴함
},
};
var slotMachine = {
reels: [Object.create(reel), Object.create(reel), Object.create(reel)], //코드작성
spin() {
this.reels.forEach(function spinReel(reel) {
reel.spin();
});
},
display() {
// this.reels.forEach((reel) => console.log(reel.display()));
//reels는 3개의 reel(객체)이 저장된 배열, 각position을 설정해주기위해 spin을 했음.
var lines = [];
for (let linePos = -1; linePos <= 1; linePos++) {
//linePos=-1 : 현재릴의 앞의심볼을 가리킴, linePos=1 : 현재릴의 다음심볼을 가리킴
let line = this.reels.map(function getSlot(reel) {
var slot = Object.create(reel);
slot.position =
(reel.symbols.length + reel.position + linePos) % reel.symbols.length;
return slot.display();
});
lines.push(line.join(" | ")); //각 라인별로 출력할 심볼3개를 한줄로 만들어 lines에 추가 (line은 '❤ | ★ | ♦' 형태임)
}
return lines.join("\n"); //lines배열에 저장된 문자열 총3개를 엔터로 구분해 출력
},
};
slotMachine.spin();
console.log(slotMachine.display());
댓글