일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- presignedurl
- MySQL
- Cookie
- Git
- JavaScript
- SQL
- 방송대
- TiL
- redis
- 엘리스sw트랙
- 유노코딩
- 코딩테스트
- node.js
- 개발자취업
- 항해99
- HTML
- 데이터베이스시스템
- 코드잇
- 파이썬
- 프로그래머스
- 파이썬프로그래밍기초
- CSS
- 방송대컴퓨터과학과
- 코딩테스트준비
- nestjs
- 99클럽
- 중간이들
- 꿀단집
- Python
- aws
- Today
- Total
배꼽파지 않도록 잘 개발해요
[코드잇] 모던 자바스크립트 ② 자바스크립트 문법과 표현, 내부 기능, 모듈 본문
4. 자바스크립트의 문법과 표현
문장과 표현식
문장(statement)
· 작업을 수행하도록 명령하는 것
· 일련의 동작이나 명령들
let x = 10; // 변수 선언문
if (x > 5) { // 조건문
console.log('x는 5보다 큽니다.'); // 함수 호출문
}
표현식(Expression)
· 값으로 평가될 수 있는 코드 조각들
· 변수, 상수, 연산자, 함수 호출 등 포함
let y = 20; // 변수 선언문
let z = x + y; // 연산 표현식
문장이면서 표현식
· 할당식, 함수 호출
// 할당 연산자는 값을 할당하는 동작도 하지만, 할당한 값을 그대로 가지는 표현식
title = 'JavaScript';
// 함수 호출은 함수를 실행하는 동작도 하지만, 실행한 함수의 리턴 값을 가지는 표현식
sayHi();
// console.log 메소드는 콘솔에 아규먼트를 출력하는 동작도 하지만, undefined 값을 가지는 표현식
console.log('hi'); // undefined
조건을 다루는 표현식
조건 연산자 (Conditional operator)
· 조건 ? truthy 할 때 표현식 : falsy 할 때 표현식
· 삼항 연산자 (Ternary operator)
const CUT_OFF = 80;
function passChecker(score) {
return score > CUT_OFF ? '합격' : '불합격!';
}
console.log(passChecker(75)); // 불합격
const CUT_OFF = 80;
function passChecker(score) {
IF (score > CUT_OFF) {
return '합격!';
} else {
return '불합격!';
}
}
console.log(passChecker(75)); // 불합격
조건에 따라 변수 선언 혹은 반복문 실행 불가능
Spread 구문
· 배열을 다룰 떄 유용
· 여러 개의 값을 하나로 묶은 배열을 다시 각각의 개별값으로 펼치는 문법
· 배열 앞에 마침표 3개를 붙임.
const numbers = [1, 2, 3];
console.log(...numbers);
// console.log(1, 2, 3);과 같음.
rest parameter와 같은 형태인데, 다르게 동작함.
· rest parameter : 여러 개 아규먼트(argumen)t를 하나의 파라미터로 묶는 방식
· spread : 하나로 묶여있는 값을 각각의 개별값으로 펼치는 방식
spread구문을 활용해서 배열을 편리하게 복사할 수 있음.
객체 타입 값들은 변수에 직접 할당 (X), 주소값이 참조됨 (O)
할당 연산자를 사용해서 복사하면 원본 배열에 영향을 미침.
const webPublishing = ['HTML', 'CSS'];
const interactiveWeb = webPublishing;
interactiveWeb.push('JavaScript');
console.log(webPublishing); // [ 'HTML', 'CSS', 'JavaScript' ]
console.log(interactiveWeb); // [ 'HTML', 'CSS', 'JavaScript' ]
복사할 때 slice 메서드를 사용하여 새로운 배열 생성
원본 배열에 영향을 미치지 않도록 함.
slice 구문으로 배열을 합침
const webPublishing = ['HTML', 'CSS'];
const interactiveWeb = webPublishing.slice();
interactiveWeb.push('JavaScript');
console.log(webPublishing); // [ 'HTML', 'CSS' ]
console.log(interactiveWeb); // [ 'HTML', 'CSS', 'JavaScript' ]
스프레드 구문으로 배열을 합침
const webPublishing = ['HTML', 'CSS'];
const interactiveWeb = [...webPublishing, 'Javascript'];
interactiveWeb.push('JavaScript');
console.log(webPublishing); // [ 'HTML', 'CSS' ]
console.log(interactiveWeb); // [ 'HTML', 'CSS', 'JavaScript' ]
concat 메서드로 배열을 합침
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = arr1.concat(arr2);
console.log(arr4);
→ 기능은 같으나, 스프레드 구문을 사용하면 변수에 담길 배열의 모습을 직관적으로 볼 수 있음.
객체의 아규먼트로도 사용 가능함
(함수, 객체의 아규먼트 모두 가능)
const myfood = (fruit, bread) => {
console.log(`과일은 ${fruit}가 맛있어요!`)
console.log(`빵은 역시 ${bread}가 최고야!`)
};
const arr = ['peach', 'scone'];
myfood(...arr) // myfood라는 객체의 아규먼트로 사용함
주의할 점 : 스프레드 구문 자체는 값이 아님
const numbers = [1];
const number = ...numbers;
// SyntaxError: Unexpected token '...'
{...배열} 이런식으로 스프레드 구문으로 배열 쓰고 중괄호를 붙이면 객체가 만들어짐.
이때 객체의 프로퍼티 네임은 해당 프로퍼티 값의 인덱스임
const members = ['길동', '또치', '둘리'];
const newObject = {...members};
console.log(newObject); // { '0': '길동', '1': '또치', '2': '둘리' }
splice(시작인덱스, 개수)
배열의 원소 중 시작인덱스부터 N개를 제거
let fruits = ['apple', 'banana', 'orange', 'grape'];
// 배열의 1번 인덱스부터 2개의 요소를 제거
fruits.splice(1, 2);
console.log(fruits); // ['apple', 'grape']
객체 Spread 하기
ES2018에서 일반 객체에도 Spread 구문 사용 가능
const codeit = {
name: 'codeit',
};
const codeitClone = {
...codeit, // spread 문법!
};
console.log(codeit); // {name: "codeit"}
console.log(codeitClone); // {name: "codeit"}
객체로는 새로운 배열을 만들거나 함수의 아규먼트로 사용할 수는 없음.
객체를 spread할 때는 반드시 객체를 표현하는 중괄호 안에서 활용해야 함.
모던 프로퍼티 표기법
활용할 변수의 이름과 프로퍼티네임이 똑같다면 하나만 작성해도 됨.
const title = '꼽파';
const birth = 1004;
const job = '식도락가';
const user = {
title, // title: title
birth: birth,
job: job,
};
객체 내 메서드에서는 콜론과 function 키워드 생략해도 됨.
const user = {
firstName: "길동",
lastName: "홍",
getFullName: function() {
return `${this.firstName} ${this.lastName}`
},
};
console.log(user.getFullName());
const user = {
firstName: "길동",
lastName: "홍",
getFullName: { // function이랑 콜론 생략해도 됨
return `${this.firstName} ${this.lastName}`
},
};
console.log(user.getFullName());
계산된 속성명(computed property name)
표현식의 값을 대괄호로 감싸면 표현식을 프로퍼티 네임으로 쓸 수 있음
const user = {
[표현식]: 값,
};
const user = {
['Code' + 'it']: 'value',
};
console.log(user);
const user = {
name: 'codeit',
birth: 2017,
getAge: () => {
const date = new Date();
return date.getFullYear() - this.birth + 1;
},
};
옵셔널 체이닝 (Optional Chaining)
· 중첩된 객체의 프로퍼티를 다룰 때 값이 null 혹은 undefined가 아니라는 것을 검증하고 접근해야 함
· 옵셔널 체이닝 연산자 왼편의 프로퍼티 값이 undefined 또는 null이 아니라면 그다음 프로퍼티 값을 리턴하고 그렇지 않은 경우에는 undefined를 반환
· ECMAScript2020에서 등장
const user = {
id: 1,
name: 'John',
address: {
city: 'New York',
zipcode: '10001'
}
};
// 옵셔널 체이닝을 사용한 안전한 프로퍼티 접근
const city = user?.address?.city;
console.log(city); // 'New York'
const country = user?.address?.country;
console.log(country); // undefined
null 병합 연산자와 함께 활용 가능
function printCatName(user) {
console.log(user.cat?.name ?? '함께 지내는 고양이가 없습니다.');
}
const user2 = {
name: 'Young',
}
printCatName(user2); // 함께 지내는 고양이가 없습니다.
구조 분해
구조 분해 (Destructuring)
배열이나 객체의 구조를 분해하는 문법
const rank = ['길동', '또치', '둘리', '희동'];
const macbook = rank[0]; // 길동
const ipad = rank[1]; // 또치
const airpods = rank[2]; // 둘리
const coupon = rank[3]; // 희동
console.log(macbook);
console.log(ipad);
console.log(airpods);
console.log(coupon);
const rank = ['길동', '또치', '둘리', '희동'];
const [macbook, ipad, airpods, coupon] = rank;
console.log(macbook); // 길동
console.log(ipad); // 또치
console.log(airpods); // 둘리
console.log(coupon); // 희동
배열의 형태를 한 변수 이름에 "배열"을 할당함.
만약 할당받는 쪽이 배열이 아니거나, 아무 것도 없으면 에러가 남.
const rank = ['길동', '또치', '둘리', '희동'];
const [macbook, ipad, airpods] = '1, 2, 3';
console.log(macbook); // 1
console.log(ipad); // ,
console.log(airpods); //
이 경우는 문자열을 할당하니까 문자열의 인덱스 번호대로 할당되는 것을 볼 수 있음.
배열의 길이는 상관이 없음. 왜냐하면 인덱스 순서대로만큼만 할당됨.
가장 마지막 파라미터에 마침표 3개 → 나머지 요소가 배열에 할당됨
const rank = ['길동', '또치', '둘리', '희동'];
const [macbook, ipad, ...airpods] = rank;
console.log(macbook); // 길동
console.log(ipad); // 또치
console.log(airpods); // [ '둘리', '희동' ]
배열의 남은 변수에는 undefined가 할당됨.
const rank = ['길동', '또치'];
const [macbook, ipad, airpods] = rank;
console.log(macbook); // 길동
console.log(ipad); // 또치
console.log(airpods); // undefined
할당하는 배열의 길이가 선언된 배열의 개수보다 적으면 남은 변수에는 undefined가 할당됨.
const rank = ['길동', '또치'];
const [macbook, ipad, airpods = "없음"] = rank;
console.log(macbook); // 길동
console.log(ipad); // 또치
console.log(airpods); // 없음
destructuring 문법을 활용해서 변수 값을 교환할 수 있음
// destructuring 문법 등장 전 교환 방법
let temp = macbook;
macbook = ipad;
ipad = temp;
// destructuring 문법으로 교환 방법
[macbook, ipad] = [ipad, macbook];
객체는 프로퍼티 네임을 통해 분해가 됨.
할당 연산자 오른편 객체에서 할당 연산자의 왼편에 선언된 변수의 이름과 똑같은 프로퍼티 네임이 있으면 그 변수 이름에 값이 할당됨.
const macbook = {
title: '맥북 프로 16형',
price: 369000,
memory: '16GB',
storage: '1TB SSD 저장 장치',
display: '16형 Retina 디스플레이',
};
// const titile = macbook.title;
// const price = macbook.price;
const {title, price} = macbook;
console.log(title); // 맥북 프로 16형
console.log(price); // 369000
객체에 존재하지 않는 프로퍼티 네임으로 선언이 되어 있으면 undefined 값이 할당됨.
const macbook = {
title: '맥북 프로 16형',
price: 369000,
memory: '16GB',
storage: '1TB SSD 저장 장치',
display: '16형 Retina 디스플레이',
};
// const titile = macbook.title;
// const price = macbook.price;
const {title, color} = macbook; // color는 객체에 존재 X
console.log(title); // 맥북 프로 16형
console.log(color); // undefined
할당연산자를 통해 기본값이 지정될 수 있음.
const macbook = {
title: '맥북 프로 16형',
price: 369000,
memory: '16GB',
storage: '1TB SSD 저장 장치',
display: '16형 Retina 디스플레이',
};
// const titile = macbook.title;
// const price = macbook.price;
const {title, color = 'silver'} = macbook; // 기본값을 설정
console.log(title); // 맥북 프로 16형
console.log(color); // silver
rest parameter 이용
const macbook = {
title: '맥북 프로 16형',
price: 369000,
memory: '16GB',
storage: '1TB SSD 저장 장치',
display: '16형 Retina 디스플레이',
};
// const titile = macbook.title;
// const price = macbook.price;
const { title, ...rest } = macbook;
console.log(title); // 맥북 프로 16형
console.log(rest); // 나머지 객체가 모두 담김
객체에서 변수를 할당할 때 새로운 이름으로 변수를 선언할 수 있음
const macbook = {
tiltle: '맥북 프로 16형',
price: 369000,
memory: '16GB',
storage: '1TB SSD 저장 장치',
display: '16형 Retina 디스플레이',
};
// const titile = macbook.title;
// const price = macbook.price;
const {title: product, ...rest} = macbook;
console.log(product);
console.log(rest);
활용할 때 : 객체 내부 프로퍼티 이름을 변수로 사용하기 힘들 때
ex. 'serial-num'
→ const { 'serial-num': serialNum } = macbook;
대괄호를 활용해서 지정하는 방법도 있음
const propertyName = 'title';
const { [propertyName]: product } = macbook;
함수와 Destructuring
함수가 리턴하는 값이 배열일 때 활용
function getArray() {
return ['컴퓨터', '냉장고', '세탁기'];
}
const [el1, el2, el3] = getArray);
console.log(el1);
console.log(el2);
console.log(el3);
객체에서 destructuring 문법 활용
// 객체 정의
const myObject = {
name: 'John',
age: 30,
city: 'New York'
};
// 함수 정의 (비구조화를 사용하여 객체의 프로퍼티를 추출)
// 파라미터에서 바로 destructuring 가능
function printObjectProperty({ name, age, city }) {
console.log(`Name: ${name}`);
console.log(`Age: ${age}`);
console.log(`City: ${city}`);
}
// 함수 호출
printObjectProperty(myObject);
돔 이벤트에서도 활용 가능
const btn = document.querySelector('#btn');
btn.addEventListener('click', ({target}) => {
target.classList.toggle('checked)');
});
중첩 객체 구조 분해 (Nest Object Destructuring)
const btn = document.querySelector('#btn');
btn.addEventListener('click', ({target: { classList }) => {
target.classList.toggle('checked)');
});
객체의 속성을 함수의 내에서 참조하는 방법
const music1 = { title: '난치병', singer: '하림' };
const music2 = { title: '너의 모든 순간', singer: '성시경' };
const music3 = { title: '무릎', singer: '아이유' };
const music4 = { title: '옛사랑', singer: '이문세' };
const music5 = { title: '한숨', singer: '이하이' };
const music6 = { title: '추억의 책장을 넘기면', singer: '이선희' };
printFavoritSong('영훈', music4);
printFavoritSong('동욱', music1);
printFavoritSong('대위', music3);
printFavoritSong('소원', music2);
printFavoritSong('우재', music5);
printFavoritSong('영준', music6);
// 방법1
function printFavoritSong(name, music) {
console.log(`최근 '${name}'님이 즐겨듣는 노래는 '${music.singer}'의 '${music.title}'이라는 노래입니다.`);
}
// 방법2
function printFavoritSong(name, music) {
const { singer, title } = music;
console.log(`최근 '${name}'님이 즐겨듣는 노래는 '${singer}'의 '${title}'이라는 노래입니다.`);
}
// 방법3
function printFavoritSong(name, { title, singer }) {
console.log(`최근 '${name}'님이 즐겨듣는 노래는 '${singer}'의 '${title}'이라는 노래입니다.`);
}
에러와 에러 객체
에러 객체 : name, message 프로퍼티가 존재함
ReferenceError | 변수가 정의되지 않았는데 참조되었을 때 발생 |
TypeError | 변수 또는 매개변수의 데이터타입이 부적절하게 사용되었을 때 발생 잘못된 타입의 메서드를 호출하거나, 부적절한 데이터 타입으로 연산 시도했을 때 발생 |
SyntaxError | 문법 오류로 인해 코드가 실행되지 않을 때 발생함. 실행되기 전에 에러를 발생시킴 |
직접 에러 객체를 만들기
자바스크립트에서는 개발자가 직접 에러 객체를 생성하여 throw
// 에러 객체 생성
const customError = new Error('사용자 정의 에러가 발생했습니다.');
// 에러 발생
throw customError;
try catch문
catch문을 통해 에러를 다루면 프로그램이 멈추지 않음.
// try catch 문
try {
// 코드
} catch (error) {
// 에러가 발생했을 때 동작할 코드
}
try {
console.log('에러 전') // 에러 전
const apple = '사과';
console.log(apple) // 사과
// const 변수에 재할당 -> 에러
apple = 'apple';
const language = 'JavaScript';
console.log(language);
} catch (e) {
console.log('에러 후');
console.error(e); // TypeError: Assignment to constant variable.
console.log(e.name); // TypeError
console.log(e.message); // Assignment to constant variable.
}
let이나 const로 try나 catch문 안에 변수를 선언하면, 블록 바깥에서 사용이 불가능함.
try 블록에서 에러가 발생하면 해당 에러 객체가 catch 블록의 매개변수로 전달됨.
finally 문
finally문에서 에러가 발생하면 finally문 안에서 try-catch문을 써야됨.
try {
try {
// 실행할 코드
} catch (err) {
// 에러가 발생했을 때 실행할 코드
} finally {
// 항상 실행할 코드
}
} catch (err) {
// finally문에서 에러가 발생했을 때 실행할 코드
}
function exampleFunction() {
try {
// 예외가 발생할 수 있는 코드 블록
console.log('try 블록 시작');
// 임의로 예외 발생
undefinedFunction(); // 이 함수는 정의되어 있지 않으므로 예외 발생
console.log('try 블록 끝'); // 이 부분은 실행되지 않음
} catch (error) {
// 예외가 발생했을 때 실행되는 코드 블록
console.error('catch 블록 시작');
console.error('에러 메시지:', error.message);
console.error('catch 블록 끝');
} finally {
// 예외 발생 여부와 상관없이 반드시 실행되는 코드 블록
console.log('finally 블록 시작');
console.log('finally 블록 끝');
}
}
// 함수 호출
exampleFunction();
5. 자바스크립트의 유용한 내부 기능
forEach와 map
forEach
각 배열 요소에 대해 주어진 함수를 실행, 주로 배열을 수정할 때 사용함.
// forEach
const members = ['a', 'b', 'c', 'd'];
for (let member of members) {
console.log(`${member}님이 입장하셨습니다.`);
}
// 메소드를 호출할 때 아규먼트로 콜백함수를 작성
members.forEach(function (member) {
console.log(`${member}님이 입장하셨습니다.`);
});
// 인덱스와 배열 원소를 동시에 출력 가능
members.forEach((member, index) => {
console.log(`${index} ${member}님이 입장하셨습니다.`);
});
// 배열값 자체에 forEach 메소드 활용
['a', 'b', 'c', 'd'].forEach((member, index, arr) => {
console.log(`${index + 1}번 ${member}님이 입장하셨습니다.`);
});
map
콜백함수 내에서 리턴문을 작성해주면 각 리턴값으로 구성된 새로운 배열이 리턴값으로 나옴.
const firstNames = ['길동', '우너', '이콜'];
const lastNames = ['고', '도', '마'];
const fullNames = firstNames.map((firstName, i) => {
return lastNames[i] + firstName;
});
console.log(fullNames);
const firstNames = ['길동', '우너', '이콜'];
const lastNames = ['고', '도', '마'];
const fullNames = firstNames.map((firstName, i) => lastNames[i] + firstName);
console.log(fullNames); // [ '고길동', '도우너', '마이콜' ]
· 단순한 배열의 반복 작업 : forEach
· 배열의 반복 작업을 통해 새로운 배열이 필요한 경우 : map
filter와 find
둘다 배열에서 조건에 맞는 값을 찾는 메소드
filter
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 짝수만 필터링
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4, 6, 8, 10]
find
const fruits = ['apple', 'banana', 'orange', 'grape', 'kiwi'];
// 'orange'를 찾기
const foundFruit = fruits.find(fruit => fruit === 'orange');
console.log(foundFruit); // 'orange'
filter와 find의 비교
filter | find | |
방식 | array.filter(element => condition); | array.find(element => condition); |
목적 | 조건을 만족하는 모든 요소를 찾아서 새 배열로 반환 없으면 빈 배열 반환 (mdn 사이트에서 확인) |
조건을 만족하는 첫 번째 요소를 찾아서 반환 없으면 undefined 반환 |
반복 | 배열의 처음부터 끝까지 반복하며 각 요소의 조건 확인 | 배열의 첫 번째 조건을 만족하는 요소를 찾은 후 반복을 종료함 |
// 배열 선언
const numbers = [1, 2, 3, 4, 5];
// find: 조건에 맞는 첫 번째 값을 찾음
const findResult = numbers.find((value) => value > 2);
if (findResult !== undefined) {
console.log('find 결과:', findResult);
} else {
console.log('조건에 맞는 값이 없습니다.');
}
// 배열 선언
const numbers = [1, 2, 3, 4, 5];
// filter: 모든 값을 필터링하여 조건에 맞는 값을 배열로 반환
const filterResult = numbers.filter((value) => value > 3);
if (filterResult.length > 0) {
console.log('filter 결과:', filterResult);
} else {
console.log('조건에 맞는 값이 없습니다.');
}
// filter 결과: [ 4, 5 ]
some과 every
some
조건을 만족하는 요소가 1개 이상 있는지
조건에 맞는 요소 하나 나오면 true 리턴하고 반복 종료
every
모든 요소가 조건을 만족하는지
예외 요소 하나 나오면 false 리턴하고 반복 종료
주의할 점은 빈 배열의 경우 조건과 무관하게 true를 반환함 (mdn)
const numbers = [1, 3, 5, 7, 9];
// some : 조건을 만족하는 요소가 1개 이상 있는지
const someReturn = numbers.some((el) => el > 5);
// every: 모든 요소가 조건을 만족하는지
const everyReturn = numbers.every((el) => el > 5);
console.log('some:', someReturn); // true (7, 9)
console.log('every:', everyReturn); // false (예외가 있으니까)
reduce
const numbers = [1, 2, 3, 4];
numbers.reduce((acc, el, i, arr) => {
return nextAccValue;
}, initialAccValue);
const numbers = [1, 2, 3, 4];
const sumAll = numbers.reduce((acc, el, i) => {
console.log(`${i}번 index의 요소로 콜백함수가 동작중입니다`)
console.log(`acc:`, acc);
console.log(`el:`, el);
console.log('-----------');
return acc + el;
}, 0);
console.log('sumAll:', sumAll);
/*
0번 index의 요소로 콜백함수가 동작중입니다
acc: 0
el: 1
-----------
1번 index의 요소로 콜백함수가 동작중입니다
acc: 1
el: 2
-----------
2번 index의 요소로 콜백함수가 동작중입니다
acc: 3
el: 3
-----------
3번 index의 요소로 콜백함수가 동작중입니다
acc: 6
el: 4
-----------
sumAll: 10
*/
두 번째 파라미터인 0이라는 초기값 생략하면?
const numbers = [2, 4, 6, 8];
const sumAll = numbers.reduce((acc, el, i) => {
console.log(`${i}번 index의 요소로 콜백함수가 동작중입니다`)
console.log(`acc:`, acc);
console.log(`el:`, el);
console.log('-----------');
return acc + el;
}); // 초기값 생략
console.log('sumAll:', sumAll);
1번 index의 요소로 콜백함수가 동작중입니다
acc: 2
el: 4
-----------
2번 index의 요소로 콜백함수가 동작중입니다
acc: 6
el: 6
-----------
3번 index의 요소로 콜백함수가 동작중입니다
acc: 12
el: 8
-----------
sumAll: 20
초기값을 생략한 경우 :
0번 인덱스 (첫 번째 인덱스)값이 acc로 들어가는 걸 볼 수 있음.
el은 두 번째 인덱스부터 시작함.
initialValue를 제공하지 않으면, reduce()는 인덱스 1부터 시작해 콜백 함수를 실행하고 첫 번째 인덱스는 건너 뜁니다. initialValue를 제공하면 인덱스 0에서 시작합니다. (출처 : mdn)
map과 reduce 활용하기
const data = [
{ type: 'apple', count: 23 },
{ type: 'banana', count: 30 },
{ type: 'orange', count: 24 },
{ type: 'grapes', count: 5 },
];
// data라는 배열의 각 객체의 count를 합해야 하는 상황
const totalCount = data.map( item => item['count'] ).reduce( (a, b) => a + b, 0)
console.log(`과일의 개수는 총 ${totalCount}개입니다.`);
map 메소드를 활용하여 배열을 생성함.
생성한 배열을 reduce 메소드를 활용하여 배열 내 모든 원소의 값을 구함.
const data = [
{ type: 'apple', count: 23 },
{ type: 'banana', count: 30 },
{ type: 'orange', count: 24 },
{ type: 'grapes', count: 5 },
];
// data라는 배열의 각 객체의 count를 합해야 하는 상황
const totalCount = data.reduce( (a, b) => a + b.count, 0)
console.log(`과일의 개수는 총 ${totalCount}개입니다.`);
data가 배열이므로 reduce를 써주고, element 부분을 b.count로 작성해서
프로퍼티네임이 count인 값만 더하도록 해도 됨.
sort, reverse
sort
· sort 메소드 자체를 사용하면 배열이 유니코드에 정의된 문자열 순서에 따라 정렬됨.
→ sort 메소드에 콜백함수를 아규먼트로 작성해야함.
· sort를 사용하면 원본 배열 자체가 정렬됨.
→ slice 메소드로 복사할 수 있음.
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) | 주어진 키에 대한 값을 설정하거나, 이미 존재하는 키의 값을 업데이트 |
has(key) | 주어진 키가 'Map' 안에 존재하는지 여부를 확인 (true / false) |
get(key) | 주어진 키에 대한 값을 반환 |
keys() | Map의 모든 키를 포함하는 새로운 Iterator 객체 반환 |
values() | Map의 모든 값들을 포함하는 새로운 Iterator 객체 반환 |
entries() | Map의 모든 키-값 쌍을 포함하는 새로운 Iterator 객체를 반환 |
size | Map에 포함된 키-값 쌍의 개수를 반환 (배열.length와 유사) |
delete(key) | 주어진 키에 해당하는 항목을 Map에서 삭제 |
clear() | Map의 모든 요소를 제거 |
// Map 객체 생성
let myMap = new Map();
// set 메소드로 키-값 쌍 추가
myMap.set('name', 'John');
myMap.set('age', 25);
// has 메소드로 특정 키의 존재 여부 확인
console.log(`Has 'name': ${myMap.has('name')}`); // 출력: Has 'name': true
console.log(`Has 'gender': ${myMap.has('gender')}`); // 출력: Has 'gender': false
// get 메소드로 특정 키에 대한 값을 가져오기
console.log(`Age: ${myMap.get('age')}`); // 출력: Age: 25
// keys 메소드로 모든 키 가져오기
console.log(`Keys: ${[...myMap.keys()]}`); // 출력: Keys: name,age
// values 메소드로 모든 값 가져오기
console.log(`Values: ${[...myMap.values()]}`); // 출력: Values: John,25
// entries 메소드로 모든 키-값 쌍 가져오기
console.log(`Entries: ${[...myMap.entries()]}`); // 출력: Entries: name,John,age,25
// size 속성으로 Map의 크기 확인
console.log(`Map size: ${myMap.size}`); // 출력: Map size: 2
// delete 메소드로 특정 키 삭제
myMap.delete('age');
console.log(`After deleting 'age': ${[...myMap.entries()]}`); // 출력: After deleting 'age': name,John
Set
중복을 허용하지 않는 값들을 모을 때 사용함.
개별 값에 바로 접근하는 방법이 없음.
메소드 | 설명 |
add(value) | 값을 추가하는 메소드 |
has(value) | 주어진 키가 'set' 안에 존재하는지 여부를 확인 (true / false) |
delete(value) | 해당 값을 제거 |
clear() | set 안의 모든 요소를 제거 |
size | 요소 개수를 반환하는 프로퍼티 |
const fruits = ['사과', '배', '포도', '바나나', '포도', '사과', '배']
const uniquefruits = new Set(fruits);
console.log(uniquefruits); // Set(4) { '사과', '배', '포도', '바나나' }
6. 자바스크립트 모듈
모듈
하나의 프로그램을 여러 개의 파일로 모듈화 하는 방식 → 효율적인 코드 관리, 재사용 가능
ES2015에는 모듈화 표준문법이 생김.
모듈 파일의 조건
· 모듈 스코프 (Module Scope) : 모듈 파일이 가지는 독립적인 scope
· 모듈 파일 안에서 선언한 변수는 외부에서 자유롭게 접근할 수 없도록 막아야 함. ( = 모듈 스코프를 가져야 함.)
· 브라우저에서 내 컴퓨터 안에 있는 html불러오면 모듈 문법 사용할 수 없음.
(문법 자체의 보안 요구사항으로 에러가 발생하도록 함.)
· HTML파일에서 자바스크립트 파일을 불러올 때 모듈 스코프를 갖게 하려면 script태그에 type속성을 module이라는 값으로 지정해 주어야 함.
export를 붙이면 다른 파일에서 사용 가능함.
export const title = 'CodeitPrinter';
import로 변수와 함수를 사용하고자 하는 파일에서 한번 더 모듈 문법으로 불러오는 과정을 거쳐야 사용 가능함.
import {title, print} from './printer.js';
print(title);
결론
- 내보내기 export
- 불러오기 import
→ 이렇게 되면 <script> 태그 안에 쓸 필요가 없어짐. html에는 진입점 하나만 불러오면 됨.
모듈 문법
index.js
// 모듈 문법
import { title, print } from './printer.js';
const title = 'Codeit'; // error
print(title);
index.js
// 모듈 문법
import { title as printerTitle, print } from './printer.js';
// index.js에서는 title을 printerTitle로 사용됨
const title = 'Codeit';
print(title);
여러 모듈을 불러오다보면 일반적인 변수명은 겹치는 경우가 많음.
import { title as printerTitle, print } from './printer.js';
import { title, data } from './members.js';
print(title);
이름 바꾸기
의도를 가지고 변수명을 변경하는 경우도 있음.
원래 이름 as 변경할 이름
printer.js
// 모듈 조건
export const title = 'Printer';
export function print(value) {
console.log(value);
}
export const data = ['길동', '또치', '둘리', '희동', '도우너', '마이콜']
index.js
// 모듈 문법
import { title as printerTitle, print } from './printer.js';
// index.js에서는 title을 printerTitle로 사용됨
import { data as members } from './printer.js';
const title = 'Codeit';
print(title);
print(members); // ['길동', '또치', '둘리', '희동', '도우너', '마이콜']
한꺼번에 다루기
import * (와일드 카드 문자)
// 모듈 안에 있는 대상 모두 불러오기
import * as printJS from './printer.js';
console.log(printerJS.title);
// 프로퍼티 형식으로 불러오기 때문에 이름 중복의 문제가 없음
export
선언문마다 X, 내보낼 대상을 중괄호 안에 모두 담아줌
export { title as printerTitle, print };
default export
default 키워드는 파일 내에서 딱 하나만 사용해야 됨 (안 그러면 에러)
export default 변수나 함수 이름
export default 'apple';
import default as apple from './fruits.js';
· Named Export : 여러개 대상 불러오기
· Default Export : 한 개 대상 불러오기
default export 부분만 바깥으로 빼올 수 있음
import {
default apple as apple,
title as memberTitle,
} from './member.js';
import apple, {
title as memberTitle,
} from './member.js';
이렇게 구분할 수 있으나, 복잡하게 작성된다는 문제가 있음.
보통 둘 중 하나를 사용하는 것이 권장됨.
export default로 객체 하나만 불러올 수 있음
export default { title, print };
// 하나의 객체를 export 하는 것임
// { title: title, print : print' }와 같다고 봄.
'코드잇 Codeit > Front-End' 카테고리의 다른 글
[코드잇] CSS 핵심개념 ② - Display, 선택자, 스타일 계산하기 (0) | 2023.12.18 |
---|---|
[코드잇] CSS 핵심개념 ① - 기본개념, 자주 쓰는 CSS 속성, 박스모델 (0) | 2023.12.17 |
[코드잇] 모던 자바스크립트 ① 모던 자바스크립트 이해, 동작원리, 함수 다루기 (0) | 2023.12.14 |
코드잇 웹 퍼블리싱 - ① 웹 퍼블리싱 시작하기 (0) | 2023.05.05 |
코드잇 javaScript 기초 - 프로그래밍과 데이터 in JavaScript ④ 과제로 복습하기 (0) | 2023.05.05 |