→ 데이터 타입이 상황에 따라 변할 수 있다! (유연한 데이터 타입)
→ Symbol
const user = Symbol('this is a user');
→ BigInt
2**53 - 1
보다 큰 정숫값도 안전하게 표현 가능console.log(9007199254740993n); // 9007199254740993n console.log(BigInt('9007199254740993')); // 9007199254740993n
→ typeof 연산자
typeof null
을 하면 문자열 null
이 리턴되는 게 아니라 문자열 object가 리턴되는 문제 (수정 제안 but 아직 반영 X)typeof
연산자를 사용하면 function이라는 값을 리턴 (객체로 취급하지만 리턴은 function)퀴즈 생략
undefined
number
string
→ 형 변환 → boolean
(true or false)
→ Falsy 값, Truthy 값
→ AND 연산자
true
일 경우 오른쪽 값, 왼쪽 값이 false
일 경우 왼쪽 값 출력→ OR 연산자
true
일 경우 왼쪽 값, 왼쪽 값이 false
일 경우 오른쪽 값 출력❗AND 연산자가 OR 연산자보다 우선순위가 높음❗
→ 물음표 두 개(??)를 사용해서 null 혹은 undefined 값을 가려내는 연산자
null 이나 undefined라면
연산자 오른편의 값이 리턴null 이나 undefined가 아니라면
연산자 왼편의 값이 리턴console.log(title); // undefined
var title = 'codeit';
console.log(title); // codeit
→ var
의 경우 변수 선언 이전에 접근이 가능하지만 값이 할당되지는 않아서 undefined
출력 + 중복 선언 가능
➕ 함수가 아닌 경우(ex. if문, for문), var은 전역 변수 처리
var x; // 함수 스코프 (function scope)
let y; // 블록 스코프 (block scope)
const z; // 블록 스코프 (block scope)
함수 선언
함수 표현식
const printCodeit = function () {
console.log('Codeit');
}
printCodeit();
Named Function Expression (기명 함수 표현식)
const sayHi = function printHiInConsole() {
console.log('Hi');
};
console.log(sayHi.name); // printHiInConsole
즉시 실행 함수 (표현) → Immediately Invoked Function Expression, 줄여서 IIFE
(function (x, y) {
console.log(x + y);
})(3, 5);
➕ 일반적으로 프로그램 초기화 기능에 많이 활용
➕ 함수의 리턴값을 바로 변수에 할당하고 싶을 때 활용
→ 콜백 함수 (Callback Function) : 다른 함수의 파라미터에 전달된 함수
→ 고차 함수 (Higher Order Function) : 함수를 리턴하는 함수
→ 일급 함수 (First Order Function) : 다른 함수에 할당 가능, 파라미터로 전달 가능, 리턴 가능한 함수
파라미터(Parameter) : 외부로부터 값을 전달받기 위해 힘수를 선언할 때 작성하는 것
아규먼트(Argument) : 함수를 호출할 때 파라미터로 전달하는 값
→ 파라미터를 전달하지 않고, 기본값이 없을 때 : undefined
전달
첫번째 값
과 undefined
전달→ 두번재 파라미터에 첫번째 파라미터 값을 활용 가능
Argument의 개수에 따라 유연한 대처가 가능한 함수
function printArguments() {
for (const arg of arguments) {
console.log(arg);
}
console.log('-----------');
}
printArguments('Young', 'Mark', 'Koby');
printArguments('Captain');
printArguments('Jayden', 'Scott');
printArguments('Suri', 'Jack', 'Joy', 'Noel');
→ 배열의 역할 X
function firstWords(words) {
let word = '';
// 여기에 코드를 작성하세요
for(const arg of arguments) {
word += arg[0];
}
console.log(word);
}
firstWords('나만', '없어', '고양이');
firstWords('아니', '바나나말고', '라면먹어');
firstWords('만두', '반으로', '잘라먹네', '부지런하다');
firstWords('결국', '자바스크립트가', '해피한', '지름길');
firstWords('빨간색', '주황색', '노란색', '초록색', '파란색', '남색', '보라색');
function printArguments(...args) {
for (const arg of args) {
console.log(arg);
console.log(args.splice(0, 2));
}
console.log('-----------');
}
printArguments('Young', 'Mark', 'Koby');
printArguments('Captain');
printArguments('Jayden', 'Scott');
printArguments('Suri', 'Jack', 'Joy', 'Noel');
→ Rest Parameter는 배열이다❗ → splice 등 사용 가능
➕ 일반 파라미터와 사용 가능 (반드시 가장 마지막에 위치) → 필요에 따라 유연하게 사용 가능
// 여기에 코드를 작성하세요
function ignoreFirst(...args) {
for(const arg of args) {
let last = args.splice(1, args.length);
for(let i = 0; i < last.length; i++) {
console.log(last[i]);
}
}
}
ignoreFirst('1세대', '2세대', '3세대');
ignoreFirst('곰팡이', '강아지', '고양이');
ignoreFirst(20, 9, 18, 19, 30, 34, 40);
// 여기에 코드를 작성하세요
function ignoreFirst(first, ...rest) {
for (const el of rest) {
console.log(el);
}
}
ignoreFirst('1세대', '2세대', '3세대');
ignoreFirst('곰팡이', '강아지', '고양이');
ignoreFirst(20, 9, 18, 19, 30, 34, 40);
/*
const getTwice = function(number) {
return number * 2;
};
*/
// 1번 방법
**const getTwice = (number) => {
return number * 2;
};**
// 2번 방법
// const getTwice = number => number * 2;
console.log(getTwice(5));
const myBtn = document.querySelector('#myBtn');
myBtn.addEventListener('click', () => {
console.log('button is clicked');
});
⚠️ Arrow Function 주의사항
Argument
의 부재 → 대체 불가⚠️ 2번 방법 주의사항
return문
을 제외하고 다른 표현이 필요한 경우 불가({ name: ‘Codeit’, })
function getFullName() {
return `${this.firstName} ${this.lastName}`;
}
const user = {
firstName: 'Tess',
lastName: 'Jang',
getFullName: getFullName,
}
const admin = {
firstName: 'Alex',
lastName: 'Kim',
getFullName: getFullName,
}
console.log(user.getFullName());
console.log(admin.getFullName());
✨ This란?
→ 함수를 호출한 객체를 가리키는 키워드
(선언하지 않고 그냥 사용하게 되면 기본값인 window 객체를 가리킴)
➕ Arrow Function에서 this를 사용하는 방법
→ 일반 함수처럼 호출한 대상에 따라 상대적으로 변화 X
→ Arrow Function이 선언되기 직전에 이용한 this 값과 같은 this 값을 사용
➡️ 일반 함수에서의 사용을 권장함 👍
#️⃣ 문장 (statements)
→ 어떤 동작이 일어나도록 작성된 최소한의 코드 덩어리
#️⃣ 표현식 (expressions)
→ 결과적으로 하나의 값이 되는 모든 코드
➡️ 일반적으로 표현식인 문장은 세미콜론으로, 표현식이 아닌 문장은 문장 자체의 코드 블록(중괄호)로 그 문장의 범위가 구분
if문
switch문
조건 연산자 = 삼항 연산자
// 조건 ? truthy 할 때 표현식 : falsy 할 때 표현식
// 삼항 연산자
const CUT_OFF = 80;
const passChecker(score) {
return score > CUT_OFF ? '합격!' : '불합격!';
}
console.log(passChecker(90));
❌ 조건에 따라 변수를 선언하거나 반복문 사용 불가 (모든 if문 대체 불가)
→ 하나로 묶여있는 값을 각각의 개별 값으로 펼치는 방식 (Spread문 자체가 값 X, 여러 값의 목록으로 평가)
↔️ Rest Parameter : 여러개의 Argument를 하나로 묶는 방식
const numbers = [1, 2, 3];
console.log(**...numbers**); // 1 2 3
console.log(1, 2, 3); // 1 2 3
➕ Slice를 사용하지 않고도 배열 복사 가능 (바로 요소 추가도 가능)
const webPublishing = ['HTML', 'CSS'];
const interactiveWeb = [...webPublishing, 'JavaScript'];
// const interactiveWeb = [...webPublishing];
// interactiveWeb.push('JavaScript');
console.log(webPublishing); // ['HTML', 'CSS']
console.log(interactiveWeb); // ['HTML', 'CSS', 'JavaScript']
*️⃣ 객체 Spread
const latte = {
esspresso: '30ml',
milk: '150ml'
};
const cafeMocha = {
...latte,
chocolate: '20ml',
}
console.log(latte); // {esspresso: "30ml", milk: "150ml"}
console.log(cafeMocha); // {esspresso: "30ml", milk: "150ml", chocolate: "20ml"}
→ 객체로는 새로운 배열을 만들거나 함수의 아규먼트로 사용 불가
→ 반드시 객체를 표현하는 중괄호 안에서 활용
const title = 'Codeit';
const birth = 2024;
const job = '프로그래밍 강사';
const user = {
title,
birth,
job,
};
console.log(user);
→ 변수나 함수의 이름이 같다면 이렇게 표기 가능
→ 내부에서 사용하는 함수의 경우 function과 : 생략 가능
// 계산된 속성명 (computed property name)
const user = {
// [표현식]: 값,
['Code' + 'it']: 'value',
};
console.log(user); // {Codeit: "value"}
중첩된 객체의 프로퍼티를 다룰 때 null
혹은 undefined
가 아니라는 것을 검증하고 접근해야 에러를 방지 가능
→ AND 연산자를 활용한 방법도 객체의 이름이나 프로퍼티의 이름이 길어질수록 가독성이 나빠지는 문제 발생
→ 훨씬 더 코드를 간결하게 사용할 수 있는 문법이 옵셔널 체이닝(Optional Chaining)
옵셔널 체이닝 연산자 `?.`
function printCatName(user) {
console.log(user.cat?.name);
}
function printCatName(user) {
console.log((user.cat === null || user.cat === undefined) ? undefined : user.cat.name);
}
function printCatName(user) {
console.log(user.cat?.name ?? '함께 지내는 고양이가 없습니다.');
}
구조 분해
const rank = ['유나', '효준', '민환', '재하', '규식'];
const [macbook, ipad, airpods, ...coupon] = rank; // 적을 경우 undefined 값 할당
console.log(macbook);
console.log(ipad);
console.log(airpods);
console.log(coupon);
[macbook, ipad] = [ipad, mackbook]; // 다른 변수를 생성하지 않고도 값을 바꿔서 할당 가능
객체 구조 분해
const macbook = {
title: '맥북 프로 16형',
price: 3690000,
memory: '16GB',
storage: '1TB SSD 저장 장치',
display: '16형 Retina 디스플레이',
}
// const title = macbook.title;
// const price = macbook.price;
const { title, price } = macbook; // 같은 변수의 이름이 있으면 그 값이 할당됨 아니라면 undefined 값
const { title, ...rest } = macbook; // 앞에 선언된 것을 제외한 프로퍼티를 할당
const { title: product, price } = macbook; // 프로퍼티를 다른 이름으로 선언하고 싶다면 : 사용
const { [propertyName]: product, price } = macbook;
console.log(title);
console.log(price);
console.log(product);
함수 구조 분해
function getArray() {
return ['컴퓨터', '냉장고', '세탁기']; // 위에서 바로 활용 가능
}
const [el1, el2, el3] = getArray();
console.log(el1);
console.log(el2);
console.log(el3);
객체 구조 분해
function printSummary(object) {
const { title, color, price } = object; // 위에서 바로 활용 가능
console.log(`선택한 상품은 '$title}'입니다.`);
console.log(`색상은 ${color}이며,`);
console.log(`가격은 ${price}원 입니다.`);
};
printSummary(macbook);
const btn = document.querySelector('#btn');
btn.addEventListener('click', ({ target }) => {
target.classList.toggle('checked');
});
// + 중첩 객체 구조 분해
btn.addEventListener('click', ({ target: { classList } }) => {
classList.toggle('checked');
});
btn.addEventListener('click', ({ target }) => {
const { classList } = target;
classList.toggle('checked');
});
→ Syntax Error, Type Error 등 발생하는 에러
// try catch 문
try {
// 코드 (에러가 발생한 이후 시점의 코드는 작동 X)
} catch(error) {
// 에러가 발생했을 때 동작할 코드
console.error(error);
/*
console.log(error);
console.log(error.name);
console.log(error.message);
*/
}
try {
// 실행할 코드
} catch (err) {
// 에러가 발생했을 때 실행할 코드
} finally {
// 항상 실행할 코드
}
→ finally문에서도 에러 처리가 필요하다면 중첩해서 활용
try {
try {
// 실행할 코드
} catch (err) {
// 에러가 발생했을 때 실행할 코드
} finally {
// 항상 실행할 코드
}
} catch (err) {
// finally문에서 에러가 발생했을 때 실행할 코드
}
const quiz1 = {
question: '다음 중 스승의 날과 생일이 같은 인물은 누구일까요?',
example: [ '율곡 이이', '퇴계 이황', '세종대왕', '신사임당'],
answer: 3,
solution: '훈민정음 창제 등 우리나라 문화와 교육 발전에 남긴 업적이 가장 큰 인물이라는 평가와 함께, 이 시대의 스승이 세종대왕처럼 존경받았으면 하는 바람으로 세종대왕의 탄생일이 스승의 날로 지정되었습니다.',
};
const quiz2 = {
question: '다음 중 희노애락에 속하지 않는 것은 무엇일까요?',
example: ['사랑', '기쁨', '즐거움'],
answer: 1,
solution: '희노애락에서의 애를 사랑 애(愛)라고 자칫 오해할 수가 있지만, 희노애락의 애는 슬플 애(哀)입니다. 기쁨은 기쁠 희(喜), 즐거움은 즐거울 락(樂)에 담겨 있습니다.',
};
function printQuiz({ question, example }) {
let exMsg = '';
try {
for (let i = 0; i < example.length; i++) {
exMsg += `${i + 1}. ${example[i]} `;
}
console.log(question);
console.log(exMsg);
} catch(error) {
console.log(error.name);
}
}
// 테스트 코드
printQuiz(quiz1);
printQuiz(1);
printQuiz("");
printQuiz({});
printQuiz(quiz2);
forEach
const members = ['영훈', '윤수', '동욱', '태호'];
for (let member of members) {
console.log(`{members}님이 입장하셨습니다.`);
}
members.forEach((member, i) => {
console.log(`${i} ${member}님이 입장하셨습니다.`);
});
→ forEach
에서 첫번째 인자는 필수, index는 선택const firstNames = ['영훈', '윤수', '동욱', '태호'];
const lastNames = ['강', '이', '손', '성'];
firstNames.forEach((firstName, i) => {
console.log(`${lastNames[i]}${firstName}님이 입장하셨습니다.`);
});
→ 여러 배열에서 같은 위치의 값을 사용하도록 활용 가능map
const firstNames = ['영훈', '윤수', '동욱', '태호'];
const lastNames = ['강', '이', '손', '성'];
const fullNames = firstNames.map((firstName, i) => {
return lastNames[i] + firstName;
});
console.log(fullNames);
→ 새로운 배열을 return 한다는 차이점❗const list = document.querySelector('.list');
const data = [{
title: '자바스크립트 공부하기',
isClear: true,
}, {
title: '쓰레기 분리수거',
isClear: false,
}, {
title: '고양이 밥주기',
isClear: true,
}, {
title: '독서하기',
isClear: false,
}, {
title: '영어 공부하기',
isClear: false,
}
];
// 여기에 코드를 작성해 주세요.
data.forEach((todo, i) => { // 1번 조건
const li = document.createElement('li'); // 2번 조건
if (todo.isClear) {
li.classList.add('item', 'done'); // 4번 조건
} else {
li.classList.add('item'); // 3번 조건
}
li.textContent = `${i + 1}. ${todo.title}`; // 5번 조건
list.appendChild(li); // 6번 조건
});
const quiz = ['YUMMY', 'COUNT', 'ABUSE', 'SOUND', 'SWING'];
// 여기에 코드를 작성하세요
const answer = quiz.map((word, i) => {
return word[i];
});
// 테스트 코드
console.log(answer);
filter
const devices = [
{ name: 'GalaxyNote', brand: 'Samsung' },
{ name: 'MacbookPro', brand: 'Apple' },
{ name: 'iPad', brand: 'Apple' },
{ name: 'GalaxyWatch', brand: 'Samsung' },
{ name: 'iMac', brand: 'Apple' },
{ name: 'GalaxyBuds', brand: 'Samsung' },
{ name: 'Gram', brand: 'LG' },
{ name: 'GalaxyBook', brand: 'Samsung' },
{ name: 'SurfacePro', brand: 'Microsoft' },
{ name: 'ZenBook', brand: 'Asus' },
{ name: 'MacbookAir', brand: 'Apple' },
];
const apples = devices.filter((el) => el.brand === 'Apple');
console.log(apples);
→ filtering 된 새로운 배열 생성find
const myLaptop = devices.find((el) => el.name === 'MacbookAir');
console.log(myLaptop);
→ 한가지의 값을 찾기 (같은 값이 여러개라면 가장 위에 있는 것을 기준으로 선택) → 반복문이 중단const seoul = ['김영훈', '김윤수', '김동욱', '강대위', '김영준',
'김규식', '김태호', '김효신', '손효준', '김현승', '김재하', '김유나',
'김재훈', '김혜선', '김민환', '김규리', '김소원', '김우재', '최영준',
'김태순', '김종훈', '김성환', '김승용', '김지혜', '이승욱', '김도현',
'김승규', '윤하은', '김유진', '김정민', '김혜정', '김예진', '김여진',
'김성희', '김혜수', '김인선', '김상필', '김혜진', '서상원', '김상혜',
'김민기', '김그루', '김희지'];
// 여기에 코드를 작성하세요
const notKims = seoul.filter((name) => {
return name[0] !== '김';
});
console.log(notKims); // (6) ["강대위", "손효준", "최영준", "이승욱", "윤하은", "서상원"]
const nameInput = document.querySelector('#user-name');
const phoneInput = document.querySelector('#phone-number');
const findBtn = document.querySelector('#find');
const data = [
{ userName: '막대기', phoneNumber: '01012341111', email: 'stick@go_do_it.kr' },
{ userName: 'young', phoneNumber: '01012342222', email: 'kang@go_do_it.kr' },
{ userName: '코린이', phoneNumber: '01012343333', email: 'corin2@go_do_it.kr' },
{ userName: 'captain', phoneNumber: '01012344444', email: 'crew@go_do_it.kr' },
{ userName: 'YH', phoneNumber: '01012345555', email: 'whyH@go_do_it.kr' },
{ userName: '망고쥬스', phoneNumber: '01012346666', email: 'drinkMango@go_do_it.kr' },
{ userName: 'nemoming', phoneNumber: '01012347777', email: 'ractAngle@go_do_it.kr' },
{ userName: '강그루', phoneNumber: '01012348888', email: 'riverTree@go_do_it.kr' },
{ userName: '개룩발룩', phoneNumber: '01012349999', email: 'checkShirts@go_do_it.kr' },
{ userName: '오렌지쥬스', phoneNumber: '01012341010', email: 'delmonte@go_do_it.kr' },
];
function findEmail() {
const nameValue = nameInput.value;
const phoneValue = phoneInput.value;
// 여기에 코드를 작성하세요
const user = data.find((el) => nameValue === el.userName && phoneValue === el.phoneNumber);
const message = user
? `${user.userName}님의 이메일은 ${user.email} 입니다.`
: '이메일을 찾을 수 없습니다. 입력 정보를 다시 확인해 주세요.';
alert(message);
}
findBtn.addEventListener('click', findEmail);
// some과 every
const numbers = [1, 3, 5, 7, 9];
// some: 조건을 만족하는 요소가 1개 이상 있는지
const someReturn = numbers.some((el, i) => {
console.log('some: ', i);
return el > 5;
});
// every: 모든 요소가 조건을 만족하는지 -> 조건을 만족하지 않는 요소가 있다면 바로 중단
const everyReturn = numbers.every((el, i) => {
console.log('every: ', i);
return el > 5;
});
console.log('some: ', someReturn);
console.log('every: ', everyReturn);
const spait = [
{ codeName: 'ApplePie', members: ['스파이', '스파이', '스파이', '스파이', '스파이'] },
{ codeName: 'BigBoss', members: ['스파이', '스파이', '스과이', '스파이', '스파이'] },
{ codeName: 'CEO', members: ['스파이', '스파이', '스파이', '습하이', '스파이'] },
{ codeName: 'DeathNote', members: ['스파이', '스파이', '스파이', '스파이', '스파이'] },
{ codeName: 'EarlyBird', members: ['스파이', '스마이', '스파이', '스파이', '스파이'] },
{ codeName: 'Faker', members: ['스파이', '스파이', '스파이', '스파이', '스파이'] },
];
function checkSpy(team) {
// 여기에 코드를 작성하세요
const result = team.members.some((member) => member !== '스파이');
let message = '';
if (result) {
message = `[주의!] 팀 ${team.codeName} 에 이중 스파이가 있습니다!`;
} else {
message = `팀 ${team.codeName} 에는 이중 스파이가 없습니다.`;
}
console.log(message);
}
// 테스트 코드
spait.forEach((team) => checkSpy(team));
// reduce
const numbers = [1, 2, 3, 4];
numbers.reduce((acc, el, i, arr) => {
return nextAccValue;
}, initialAccValue);
const data = [
{ company: 'Naber', month: 3 },
{ company: 'Amajohn', month: 12 },
{ company: 'Coogle', month: 10 },
{ company: 'Ittel', month: 6 },
{ company: 'Sasung', month: 4 },
{ company: 'CaCao', month: 3 },
{ company: 'Microhard', month: 17 },
];
// 여기에 코드를 작성하세요
const totalCareer = data.reduce((acc, el) => acc + el.month, 0);
console.log(`상원이의 경력은 총 ${totalCareer}개월입니다.`);
sort
const numbers = [1, 10, 4, 21, 36000];
// 오름차순 정렬
numbers.sort((a, b) => a - b);
console.log(numbers); // (5) [1, 4, 10, 21, 36000]
// 내림차순 정렬
numbers.sort((a, b) => b - a);
console.log(numbers); // (5) [36000, 21, 10, 4, 1]
→ 메소드를 실행하는 원본 배열의 요소들을 정렬reverse
const letters = ['a', 'c', 'b'];
const numbers = [421, 721, 353];
letters.reverse();
numbers.reverse();
console.log(letters); // (3) ["b", "c", "a"]
console.log(numbers); // (3) [353, 721, 421]
→ 배열의 순서를 뒤집어 주는 메소드 → 원본 배열의 요소들을 뒤집어 정렬Map
map.set(key, value): key를 이용해 value를 추가하는 메소드.
map.get(key): key에 해당하는 값을 얻는 메소드. key가 존재하지 않으면 undefined를 반환.
map.has(key): key가 존재하면 true
, 존재하지 않으면 false
를 반환하는 메소드.
map.delete(key): key에 해당하는 값을 삭제하는 메소드.
map.clear(): Map 안의 모든 요소를 제거하는 메소드.
map.size: 요소의 개수를 반환하는 프로퍼티. (메소드가 아닌 점 주의! 배열의 length 프로퍼티와 같은 역할)
→ 메소드를 통해 값을 다루기 때문에, 다양한 자료형을 key로 활용할 수 있다는 장점
Set
set.add(value): 값을 추가하는 메소드. (메소드를 호출한 자리에는 추가된 값을 가진 Set 자신을 반환.)
set.has(value): Set 안에 값이 존재하면 true
, 아니면 false
를 반환하는 메소드.
set.delete(value): 값을 제거하는 메소드. (메소드를 호출한 자리에는 셋 내에 값이 있어서 제거에 성공하면 true, 아니면 false를 반환.)
set.clear(): Set 안의 모든 요소를 제거하는 메소드.
set.size: 요소의 개수를 반환하는 프로퍼티. (메소드가 아닌 점 주의! 배열의 length 프로퍼티와 같은 역할)
→ ❗중복을 허용하지 않는 값들을 모을 때 유용
→ 다른 파일과 함수명이 동일하면 안 됨
→ 따라서, 모듈 스코프를 가지고 있어야 함 (위의 문제 해결) <script type=”module” src=”index.js”></script>
type=”module”
을 사용했을 때 발생하는 에러 → Live Server로 서버를 통해 실행 시 해결
export
를 통해 다른 파일에서 사용할 수 있도록 ➕ import { title, print } from ‘./other.js’;
처럼 다른 파일에서 불러와서 사용
→ 여러개의 파일을 하나의 파일에 불러와서 html에서는 하나의 js만 사용
const addInput = document.querySelector('.add-input');
const list = document.querySelector('.list');
function add(data) {
const inputValue = addInput.value;
const index = data.length;
const li = document.createElement('li');
li.classList.add('item');
li.innerHTML = `<b>${index + 1}</b>${inputValue}<button class="del-btn" data-index="${index}">x</button>`;
list.append(li);
data.push(inputValue);
addInput.value = '';
addInput.focus();
}
function emptyAlert() {
alert('고민되는 메뉴를 입력해 주세요.');
addInput.focus();
}
function maxAlert() {
alert('메뉴는 최대 5개까지만 고민할 수 있습니다.');
addInput.value = '';
}
// 아래 코드를 수정해 주세요
export function addMenu(data) {
const inputValue = addInput.value;
if (inputValue === '') {
emptyAlert();
} else if (data.length > 4) {
maxAlert();
} else {
add(data);
}
}
// 여기에 코드를 작성하세요
import { addMenu } from "./add.js";
const data = [];
const addBtn = document.querySelector('.add-btn');
const addInput = document.querySelector('.add-input');
addBtn.addEventListener('click', () => addMenu(data));
addInput.addEventListener('keypress', (e) => e.code === 'Enter' && addMenu(data));
import { title **as** printerTitle, print } from ‘./other.js’;
import { addMenu } from './add.js';
// 여기에 코드를 작성하세요
import { deleteMenuByIndex as deleteMenu } from './delete.js';
const data = [];
const addBtn = document.querySelector('.add-btn');
const addInput = document.querySelector('.add-input');
const list = document.querySelector('.list');
addBtn.addEventListener('click', () => addMenu(data));
addInput.addEventListener('keypress', (e) => e.code === 'Enter' && addMenu(data));
list.addEventListener('click', ({ target }) => target.tagName === 'BUTTON' && deleteMenu(data, target.dataset.index));
import * as otherJS from ‘./other.js’;
→ console.log(otherJS.title);
export { title, print };
→ 이름 변경시 export할 때 미리 변경하기
ex. export { title **as** printerTitle , print };
import { addBtn, addInput, list } from './tags.js';
import { addInput, list } from './tags.js';
import { list } from './tags.js';
const addBtn = document.querySelector('.add-btn');
const addInput = document.querySelector('.add-input');
const list = document.querySelector('.list');
// 여기에 코드를 작성해 주세요. ( 모든 변수를 한 번에 export해 주세요. )
export { addBtn, addInput, list };
export default title;
→ 딱 한번만 사용 가능 (하나의 대상만을 export)
import title from ‘./other.js’;
→ 중괄호 없이 사용 가능
export default addMenu;
export default deleteMenu;
export default rollMenu;
import { addBtn, addInput, list, rollBtn } from './tags.js';
// 여기에 코드를 작성하세요
import addMenu from './add.js';
import deleteMenu from './delete.js';
import rollMenu from './roll.js';
const data = [];
addBtn.addEventListener('click', () => addMenu(data));
addInput.addEventListener('keypress', (e) => e.code === 'Enter' && addMenu(data));
list.addEventListener('click', ({ target }) => target.tagName === 'BUTTON' && deleteMenu(data, target.dataset.index));
rollBtn.addEventListener('click', () => list.classList.contains('rolling') || rollMenu(data));
생략
import { addBtn, addInput, list, rollBtn } from './tags.js';
// 여기에 코드를 작성하세요
import { addMenu, deleteMenu, rollMenu } from './functions.js';
const data = [];
addBtn.addEventListener('click', () => addMenu(data));
addInput.addEventListener('keypress', (e) => e.code === 'Enter' && addMenu(data));
list.addEventListener('click', ({ target }) => target.tagName === 'BUTTON' && deleteMenu(data, target.dataset.index));
rollBtn.addEventListener('click', () => list.classList.contains('rolling') || rollMenu(data));
// 여기에 코드를 작성해 주세요.
import addMenu from './functions/add.js';
import deleteMenu from './functions/delete.js';
import rollMenu from './functions/roll.js';
export { addMenu, deleteMenu, rollMenu };