[Codeit boost 1기] JS 중급 (1)

김서윤·2024년 6월 8일
0

Ch1. 모던 자바스크립트


1️⃣ 모던 자바스크립트 이해하기

01~02. 모던 자바스크립트란?

  • ECMAScript → 자바스크립트 표준 명세서 ( JavaScript Specification )
    • ES6 → 정식 명칭 ECMAScript 2015
  • Modern JavaScript
    • 현시점에 사용하기 적합한 범위 내에서 최신 버전의 표준을 준수하는 자바스크립트
    • JavaScript의 기본 개념 더 견고히!
    • 새롭게 등장한 문법들 중 유용한 문법들?
    • 모던하게 자바스크립트 활용하기!

03. ECMAScript 더 알아보기

2️⃣ 자바스크립트의 동작 원리

01. 데이터 타입의 특징과 종류

→ 데이터 타입이 상황에 따라 변할 수 있다! (유연한 데이터 타입)

02. Symbol과 BigInt

→ Symbol

  • 코드 내에서 유일한 값을 가진 변수 이름을 만들 때 사용
  • 다른 어떤 값과 비교해도 true가 될 수 없는 고유한 변수
    • 똑같은 설명을 붙인 심볼을 만들더라도 두 값을 비교하면 false가 반환
  • const user = Symbol('this is a user');

→ BigInt

  • 아주 큰 정수(Integer)를 표현하기 위해 등장한 데이터 타입
  • 자바스크립트의 숫자형(number type) 값에는 9000조 정도의 정수 표현의 한계가 존재
    • 2**53 - 1 보다 큰 정숫값도 안전하게 표현 가능
  • console.log(9007199254740993n); // 9007199254740993n console.log(BigInt('9007199254740993')); // 9007199254740993n

03. typeof 연산자

→ typeof 연산자

  • 키워드 다음에 공백(띄어쓰기)을 두고 값을 작성해도 되고, 함수를 사용하듯 괄호로 감싸서 사용
  • typeof null을 하면 문자열 null이 리턴되는 게 아니라 문자열 object가 리턴되는 문제 (수정 제안 but 아직 반영 X)
  • 함수에 typeof 연산자를 사용하면 function이라는 값을 리턴 (객체로 취급하지만 리턴은 function)

04. 자바스크립트 데이터 타입의 특징 익히기

퀴즈 생략

05~06. 불린인 듯 불린 아닌 불린같은 값

undefined number string → 형 변환 → boolean (true or false)

→ Falsy 값, Truthy 값

07~09. AND와 OR의 연산 방식, 우선순위

→ AND 연산자

  • 왼쪽 값이 true일 경우 오른쪽 값, 왼쪽 값이 false일 경우 왼쪽 값 출력

→ OR 연산자

  • 왼쪽 값이 true일 경우 왼쪽 값, 왼쪽 값이 false일 경우 오른쪽 값 출력

AND 연산자가 OR 연산자보다 우선순위가 높음

10. null 병합 연산자 ??

→ 물음표 두 개(??)를 사용해서 null 혹은 undefined 값을 가려내는 연산자

  • 연산자 왼편의 값이 null 이나 undefined라면 연산자 오른편의 값이 리턴
  • 연산자 왼편의 값이 null 이나 undefined가 아니라면 연산자 왼편의 값이 리턴
  • null이나 undefined인지 확인

11~12. 변수와 스코프

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)

3️⃣ 함수 다루기

01~02. 함수를 만드는 방법

  1. 함수 선언

  2. 함수 표현식

    1. 함수 선언을 변수에 할당
    2. 함수 선언을 값처럼 사용
    const printCodeit = function () {
    	console.log('Codeit');
    }
    
    printCodeit();

03. 이름이 있는 함수 표현식

Named Function Expression (기명 함수 표현식)

const sayHi = function printHiInConsole() {
  console.log('Hi');
};

console.log(sayHi.name); // printHiInConsole

04. 즉시 실행 함수 (IIFE)

즉시 실행 함수 (표현) → Immediately Invoked Function Expression, 줄여서 IIFE

(function (x, y) {
  console.log(x + y);
})(3, 5);

➕ 일반적으로 프로그램 초기화 기능에 많이 활용

➕ 함수의 리턴값을 바로 변수에 할당하고 싶을 때 활용

05~06. 값으로서 함수

→ 콜백 함수 (Callback Function) : 다른 함수의 파라미터에 전달된 함수

고차 함수 (Higher Order Function) : 함수를 리턴하는 함수

일급 함수 (First Order Function) : 다른 함수에 할당 가능, 파라미터로 전달 가능, 리턴 가능한 함수

07~08. Parameter

파라미터(Parameter) : 외부로부터 값을 전달받기 위해 힘수를 선언할 때 작성하는 것

아규먼트(Argument) : 함수를 호출할 때 파라미터로 전달하는 값

→ 파라미터를 전달하지 않고, 기본값이 없을 때 : undefined 전달

  • 2개의 값 중 하나만 전달했을 때 : 첫번째 값undefined 전달

→ 두번재 파라미터에 첫번째 파라미터 값을 활용 가능

09. Arguments

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

10. 줄임말 대잔치

  • 실습 코드
    function firstWords(words) {
      let word = '';
    
      // 여기에 코드를 작성하세요
      for(const arg of arguments) {
        word += arg[0];
      }
      
      console.log(word);
    }
    
    firstWords('나만', '없어', '고양이');
    firstWords('아니', '바나나말고', '라면먹어');
    firstWords('만두', '반으로', '잘라먹네', '부지런하다');
    firstWords('결국', '자바스크립트가', '해피한', '지름길');
    firstWords('빨간색', '주황색', '노란색', '초록색', '파란색', '남색', '보라색');

11. Rest Parameter

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 등 사용 가능

➕ 일반 파라미터와 사용 가능 (반드시 가장 마지막에 위치) → 필요에 따라 유연하게 사용 가능

12. 1세대는 거르는게 답?

  • 실습 코드
    // 여기에 코드를 작성하세요
    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);
    

13~14. Arrow Function

/*
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문을 제외하고 다른 표현이 필요한 경우 불가
  • return값이 객체인 경우 불가 (함수의 동작 부분인 중괄호로 해석)
    • 소괄호를 한 번 감싸주면 사용 가능 ex. ({ name: ‘Codeit’, })

15~16. What is this?

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 값을 사용

➡️ 일반 함수에서의 사용을 권장함 👍

4️⃣ 자바스크립트의 문법과 표현

01. 문장과 표현식

#️⃣ 문장 (statements)

어떤 동작이 일어나도록 작성된 최소한의 코드 덩어리

#️⃣ 표현식 (expressions)

결과적으로 하나의 값이 되는 모든 코드

➡️ 일반적으로 표현식인 문장은 세미콜론으로, 표현식이 아닌 문장은 문장 자체의 코드 블록(중괄호)로 그 문장의 범위가 구분

02~03. 조건을 다루는 표현식 (조건 연산자)

  1. if문

  2. switch문

  3. 조건 연산자 = 삼항 연산자

    // 조건 ? truthy 할 때 표현식 : falsy 할 때 표현식
    // 삼항 연산자
    
    const CUT_OFF = 80;
    
    const passChecker(score) {
    	return score > CUT_OFF ? '합격!' : '불합격!';
    }
    
    console.log(passChecker(90));

    ❌ 조건에 따라 변수를 선언하거나 반복문 사용 불가 (모든 if문 대체 불가)

04~06. Spread 구문

→ 하나로 묶여있는 값을 각각의 개별 값으로 펼치는 방식 (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"}

→ 객체로는 새로운 배열을 만들거나 함수의 아규먼트사용 불가

반드시 객체를 표현하는 중괄호 안에서 활용

07~08. 모던한 프로퍼티 표기법

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"}

09. 옵셔널 체이닝

중첩된 객체의 프로퍼티를 다룰 때 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 ?? '함께 지내는 고양이가 없습니다.');
}

10~15. Destructuring (구조 분해)

구조 분해

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');
});

16~19. 에러와 에러 객체, try catch문

→ Syntax Error, Type Error 등 발생하는 에러

// try catch 문

try {
	// 코드 (에러가 발생한 이후 시점의 코드는 작동 X)
} catch(error) {
	// 에러가 발생했을 때 동작할 코드
	
	console.error(error);
	/*
	console.log(error);
	console.log(error.name);
	console.log(error.message);
	*/
}

20. finally문

try {
  // 실행할 코드
} catch (err) {
  // 에러가 발생했을 때 실행할 코드
} finally {
  // 항상 실행할 코드
}

→ finally문에서도 에러 처리가 필요하다면 중첩해서 활용

try {
  try {
    // 실행할 코드
  } catch (err) {
    // 에러가 발생했을 때 실행할 코드
  } finally {
    // 항상 실행할 코드
  }
} catch (err) {
  // finally문에서 에러가 발생했을 때 실행할 코드
}

21. 퀴즈왕의 길은 험난하다

  • 실습 코드
    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);

5️⃣ 자바스크립트의 유용한 내부 기능

❗01. 배열 메소드 1 : forEach와 map

  • 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 한다는 차이점❗

02. 할 일 정리

  • 실습 코드
    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번 조건
    });

03. 셜록 훈즈

  • 실습 코드
    const quiz = ['YUMMY', 'COUNT', 'ABUSE', 'SOUND', 'SWING'];
    
    // 여기에 코드를 작성하세요
    const answer = quiz.map((word, i) => {
      return word[i];
    });
    
    // 테스트 코드
    console.log(answer);

❗04. 배열 메소드 2 : filter와 find

  • 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);
    → 한가지의 을 찾기 (같은 값이 여러개라면 가장 위에 있는 것을 기준으로 선택) → 반복문이 중단

05. 서울 김서방 찾지 않기

  • 실습 코드
    const seoul = ['김영훈', '김윤수', '김동욱', '강대위', '김영준',
      '김규식', '김태호', '김효신', '손효준', '김현승', '김재하', '김유나',
      '김재훈', '김혜선', '김민환', '김규리', '김소원', '김우재', '최영준',
      '김태순', '김종훈', '김성환', '김승용', '김지혜', '이승욱', '김도현',
      '김승규', '윤하은', '김유진', '김정민', '김혜정', '김예진', '김여진',
      '김성희', '김혜수', '김인선', '김상필', '김혜진', '서상원', '김상혜',
      '김민기', '김그루', '김희지'];
    
    // 여기에 코드를 작성하세요
    const notKims = seoul.filter((name) => {
      return name[0] !== '김';
    });
    
    console.log(notKims); // (6) ["강대위", "손효준", "최영준", "이승욱", "윤하은", "서상원"]

06. 이메일 찾기

  • 실습 코드
    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);

❗07. 배열 메소드 3 : some과 every

// 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);

08. 이중 스파이가 있다

  • 실습 코드
    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));

❗09. 배열 메소드 4 : reduce

// reduce
const numbers = [1, 2, 3, 4];

numbers.reduce((acc, el, i, arr) => {
	return nextAccValue;
}, initialAccValue);

10. 세계적인 경력의 소유자

  • 실습 코드
    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}개월입니다.`);

11. sort, reverse

  • 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]
    
    → 배열의 순서를 뒤집어 주는 메소드 → 원본 배열의 요소들을 뒤집어 정렬

12. Map, Set

  • 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 프로퍼티와 같은 역할)

      → ❗중복을 허용하지 않는 값들을 모을 때 유용

6️⃣ 자바스크립트 모듈

01. 모듈이란?

  1. 코드를 효율적으로 관리할 수 있다!
  2. 다른 프로그램에서 재사용할 수 있다!

02, 04. 모듈 파일의 조건

→ 다른 파일과 함수명이 동일하면 안 됨

→ 따라서, 모듈 스코프를 가지고 있어야 함 (위의 문제 해결) <script type=”module” src=”index.js”></script>

03. Live Server 설치하기

type=”module”을 사용했을 때 발생하는 에러 → Live Server로 서버를 통해 실행 시 해결

05. 모듈 문법

export를 통해 다른 파일에서 사용할 수 있도록 ➕ import { title, print } from ‘./other.js’;처럼 다른 파일에서 불러와서 사용

→ 여러개의 파일을 하나의 파일에 불러와서 html에서는 하나의 js만 사용

06. 메뉴 추가 기능 붙이기

  • 실습 코드
    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));

07~08. 이름 바꾸기

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));

09. 한꺼번에 다루기

import * as otherJS from ‘./other.js’;

console.log(otherJS.title);

export { title, print };

이름 변경시 export할 때 미리 변경하기
ex. export { title **as** printerTitle , print };

10. 태그 정리하기

  • 실습 코드 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 };

11. default export

export default title;

→ 딱 한번만 사용 가능 (하나의 대상만을 export)

import title from ‘./other.js’;

→ 중괄호 없이 사용 가능

12. 간결하게 기능 붙이기

  • 실습 코드 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));

13. 복습과 활용

생략

14. 가져와서 다시 내보내기

  • 실습 코드
    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 };

0개의 댓글

관련 채용 정보