< 배열의 구조 분해 할당 >
let arr = [1, 2, 3];
let one = arr[0];
let two = arr[1];
let three = arr[2];
console.log(one, two, three); // 1 2 3
let arr = [1, 2, 3];
let [one, two, three] = arr; ①
console.log(one, two, three); // 1 2 3
위는 배열의 구조 분해 할당한 예이다.
let arr = [1, 2, 3];
let [one, two] = arr;
console.log(one, two); // 1 2
let arr = [1, 2];
let [one, two, three] = arr;
console.log(one, two, three); // 1 2 undefiend
< 객체의 구조 분해 할당 >
let person = {
name: "이정환",
age: 25,
location: "경기도"
};
let { name, age, location } = person;
console.log(name, age, location);
// 이정환 25 경기도
< 함수의 매개변수가 객체일 때 구조 분해 할당하기 >
function func({ name, age, location }) {
console.log(name, age, location);
}
let person = {
name: "이정환",
age: 25,
location: "경기도"
};
func(person);
// 이정환 25 경기도
function func({ name: n, age: a, location: l }) {
console.log(n, a, l);
}
let person = {
name: "이정환",
age: 25,
location: "경기도"
};
func(person);
// 이정환 25 경기도
< 스프레드 연산자 >
let arrA = [1, 2, 3];
let arrB = [...arrA, 4, 5, 6];
console.log(arrB); // [1, 2, 3, 4, 5, 6]
다음은 객체를 다룬 예제이다.
let objA = {
a: 1,
b: 2
};
let objB = {
...objA,
c: 3,
d: 4
};
console.log(objB); // {a: 1, b: 2, c: 3, d: 4}
< 스프레드 연산자와 함수 >
function func(a, b, c) {
console.log(a, b, c);
}
let arr = [1, 2, 3];
func(...arr); ① // 1 2 3
< 매개변수에서 구조 분해 할당과 스프레드 연산자의 차이 >
< rest 매개변수 >
function func(param, ...rest) {
console.log(param);
console.log(rest);
}
func(1, 2, 3, 4);
// 1
// [2, 3, 4]
function func(...rest, param) { // 오류 : rest 매개변수는 마지막에 작성해야 합니다.
console.log(param);
console.log(rest);
}
func(1, 2, 3, 4);
{ 요소의 추가 및 삭제 메서드 }
< push >
let food = ["짜장면", "피자", "치킨"];
const newLength = food.push("탕수육", "라자냐");
console.log(food); // ["짜장면", "피자", "치킨", "탕수육", "라자냐"]
console.log(`새로운 배열의 길이: ${newLength}`); // 새로운 배열의 길이: 5
< pop >
let food = ["짜장면", "피자", "치킨"];
const removedItem = food.pop(); // ①
console.log(removedItem); // 치킨
console.log(food); // ["짜장면", "피자"]
let food = [];
const removedItem = food.pop();
console.log(removedItem); // undefined
console.log(food); // []
< shift >
let food = ["짜장면", "피자", "치킨"];
const removedItem = food.shift(); // ①
console.log(removedItem); // "짜장면"
console.log(food); // ["피자", "치킨"]
< unshift >
let food = ["짜장면", "피자", "치킨"];
const newLength = food.unshift("갈비찜"); // ①
console.log(food); // ["갈비찜", "짜장면", "피자", "치킨"]
console.log(`새로운 배열의 길이: ${newLength}`); // 새로운 배열의 길이: 4
< shift와 unshift는 push나 pop보다 느리다 >
< slice >
arr.slice(start, end);
const arr = [1, 2, 3];
const sliced = arr.slice(2); ①
console.log(sliced); // [3]
const arr = [1, 2, 3, 4, 5];
console.log(arr.slice(-1)); ① // [5]
console.log(arr.slice(-2)); // [4, 5]
console.log(arr.slice(-3)); // [3, 4, 5]
console.log(arr.slice(-4)); // [2, 3, 4, 5]
console.log(arr.slice(-5)); // [1, 2, 3, 4, 5]
< concat >
let arrA = [1, 2];
let arrB = [3, 4];
let arrC = arrA.concat(arrB); ① //
console.log(arrC); // [1, 2, 3, 4]
console.log(arrA); ② // [1, 2]
인수로 배열이 아닌 객체를 전달해 보자.
let arrA = [1, 2];
let arrB = { a: 1, b: 2 };
let arrC = arrA.concat(arrB);
console.log(arrC); // [1, 2, { a: 1, b: 2 } ]
{ 순회 메서드 }
< forEach >
function cb(item, index, array) {
// 요소에 무언가를 할 수 있습니다.
}
arr.forEach(cb);
function cb(item, idx) {// ②
console.log(`${idx}번째 요소: ${item}`);
}
const arr = [1, 2, 3];
arr.forEach(cb); // ①
// 0번째 요소: 1
// 1번째 요소: 2
// 2번째 요소: 3
const arr = [1, 2, 3];
arr.forEach((item, idx) => { ①
console.log(`${idx}번째 요소: ${item}`);
});
// 0번째 요소: 1
// 1번째 요소: 2
// 2번째 요소: 3
{ 탐색 메서드 }
< indexOf >
arr.indexOf(item, fromIndex);
let arr = [1, 3, 5, 7, 1];
console.log(arr.indexOf(1)); // ① 0
console.log(arr.indexOf(1, -1)); // ② 4
let arr = [1, 3, 5, 7, 1];
console.log(arr.indexOf("3")); // -1
let arr = [{ name: "이정환" }, 1, 2, 3];
console.log(arr.indexOf({ name: "이정환" })); // -1
< includes >
let arr = [1, 3, 5, 7, 1];
console.log(arr.includes(3)); // true
console.log(arr.includes("생선")); // false
< findIndex >
arr.findIndex( callback(item, index, array) );
function determine(item, idx, arr) { ②
if (item % 2 === 0) {
return true;
} else {
return false;
}
}
let arr = [1, 3, 5, 6, 8];
let index = arr.findIndex(determine); ①
console.log(index); // 3
다음은 화살표와 삼항 연산자를 이용하여 간결하게 작성한 경우이다.
let arr = [1, 3, 5, 6, 8];
let index = arr.findIndex((item) =>
item % 2 === 0 ? true : false
);
console.log(index); // 3
let arr = [
{ name: "이종원" },
{ name: "이정환" },
{ name: "신다민" },
{ name: "김효빈" }
];
let index = arr.findIndex((item) => item.name === "이정환"); ①
console.log(index); // 1
< find >
let arr = [
{ name: "이종원" },
{ name: "이정환" },
{ name: "신다민" },
{ name: "김효빈" }
];
let element = arr.find((item) => item.name === "이정환"); ①
console.log(element); // {name: "이정환"}
< filter >
let arr = [
{ name: "이종원", hobby: "축구" },
{ name: "이정환", hobby: "영화" },
{ name: "신다민", hobby: "축구" },
{ name: "김효빈", hobby: "노래" }
];
let filteredArr = arr.filter(
(item) => item.hobby === "축구"
);
console.log(filteredArr);
// 출력 결과
// (2) [Object, Object]
// 0: Object
// name: "이종원"
// hobby: "축구"
// 1: Object
// name: "신다민"
// hobby: "축구"
{ 변형 메서스 }
< map >
arr.map( callback(item, index, array) );
let arr = [1, 2, 3, 4];
let newArr = arr.map((item) => item * 3); // ①
console.log(newArr); // [3, 6, 9, 12]
let arr = [
{ name: "이종원", hobby: "축구" },
{ name: "이정환", hobby: "영화" },
{ name: "신다민", hobby: "축구" },
{ name: "김효빈", hobby: "노래" }
];
let newArr = arr.map((item) => item.name);
console.log(newArr);
< sort >
arr.sort( compare( a, b ) )
let arr = [10, 5, 3];
arr.sort();
console.log(arr); // [10, 3, 5]
function compare(a, b) {
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
let arr = [10, 5, 3];
arr.sort(compare);
console.log(arr); // [3, 5, 10]
< join >
let arr = ["안녕", "나는", "이정환"];
console.log(arr.join()); // ① 안녕,나는,이정환
console.log(arr.join("-")); // ② 안녕-나는-이정환
< reduce >
arr.reduce( ( acc, item, index, array ) => {
(...)
}, initial );
let arr = [1, 2, 3, 4, 5];
let result = arr.reduce((acc, item) => acc + item, 0);
console.log(result); // 15
< date 객체 생성하기 >
let date = new Date();
console.log(date);
// 현재 날짜 및 시간
생성자: 자바스크립트의 생성자는 객체를 생성하는 함수이다. Date 객체는 리터럴이 아닌 생성자로 만든다. 생성자로 객체를 만들 때 특정 시간 등의 정보를 인수로 전달하면, 객체를 생성함과 동시에 초기화할 수 있다.
< 협정 세계시 >
시간의 시작을 1970년 1월 1일 0시 0분 0초를 기준으로 하며, 이 시작 시각을 UTC+0시라고 표현한다.
let Jan01_1970 = new Date(0);
console.log(Jan01_1970);
// Thu Jan 01 1970 09:00:00 GMT+0900 (한국 표준시)
1970년 1월 1일 9시 0분 0초로 출력되는 것을 볼 수 있는데, 이는 한국 표준시가 UTC보다 9시간이 빠르기 때문이다.
< 타임스탬프 >
특정 시간이 UTC+0시인 1970년 첫날을 기준으로 흘러간 밀리초(ms)의 시간을 의미한다.
24시간에 해당하는 밀리초를 인수로 전달하면, UTC+0에서 하루가 지난 값을 반환한다.
하루에 해당하는 밀리초는 24 * 3600 * 1000이다.
다음과 같이 생성된 Date 객체에서 역으로 타임스탬프를 구할 수도 있다.
let Jan02_1970 = new Date(24 * 3600 * 1000);
console.log(Jan02_1970.getTime());
// 86400000
{ 원하는 날짜로 Date 객체 생성하기 }
< 문자열로 특정 날짜 전달하기 >
다음 4개의 Date 객체 생성자에 인수로 전달하는 날짜는 각각 다른 형식의 문자열이다.
let date1 = new Date("2000-10-10/00:00:00"); ①
let date2 = new Date("2000.10.10/00:00:00"); ②
let date3 = new Date("2000/10/10/00:00:00"); ③
let date4 = new Date("2000 10 10/00:00:00"); ④
console.log("1:", date1); // 1: Tue Oct 10 2000 00:00:00 GMT+0900 (한국 표준시)
console.log("2:", date2); // 2: Tue Oct 10 2000 00:00:00 GMT+0900 (한국 표준시)
console.log("3:", date3); // 3: Tue Oct 10 2000 00:00:00 GMT+0900 (한국 표준시)
console.log("4:", date4); // 4: Tue Oct 10 2000 00:00:00 GMT+0900 (한국 표준시)
< 숫자로 특정 날짜 전달하기 >
year, month, date, hours, minutes, seconds, milliseconds 순서이다.
let date1 = new Date(2000, 10, 10, 0, 0, 0, 0);
let date2 = new Date(2000, 9, 10);
console.log("1:", date1); // 1: Fri Nov 10 2000 00:00:00 GMT+0900 (한국 표준시)
console.log("2:", date2); // 2: Tue Oct 10 2000 00:00:00 GMT+0900 (한국 표준시)
Date 객체가 해당 월의 시작을 1이 아니라 0부터 시작하기 때문에 1월은 0, 12월은 11로 전달해야 원하는 출력 결과를 얻을 수 있다.
< 타임스탬프로 날짜 생성하기 >
문자열이나 객체보다 저장 공간을 훨씬 적게 차지하여 빠른 비교와 탐색이 가능하다.
let date = new Date(2000, 9, 10);
let timeStamp = date.getTime(); // ①
console.log(timeStamp); // 971103600000
let dateClone = new Date(timeStamp); // ②
console.log(dateClone); // Tue Oct 10 2000 00:00:00 GMT+0900 (한국 표준시)
{ Date 객체에서 날짜 요소 얻기 }
< getFullYear >
let date = new Date(2000, 9, 10);
console.log(date.getFullYear()); // 2000
< getMonth >
let date = new Date(2000, 9, 10);
console.log(date.getMonth()); // 9
< getDate >
let date = new Date(2000, 9, 10);
console.log(date.getDate()); // 10
< getDay >
let date = new Date(2000, 9, 10);
console.log(date.getDay()); // 2
< getHours, getMinutes, getSeconds, getMilliseconds >
{ Date 객체의 날짜 요소 수정하기 }
< setFullYear >
let date = new Date(2000, 9, 10);
date.setFullYear(2021);
console.log(date); // Sun Oct 10 2021 00:00:00 GMT+0900 (한국 표준시)
< setMonth>
< setDate >
< setHours, setMinutes, setSeconds >
let date = new Date(2000, 9, 10);
date.setHours(1);
date.setMinutes(1);
date.setSeconds(1);
console.log(date); // Tue Oct 10 2000 01:01:01 GMT+0900 (한국 표준시)
{ Date 객체 출력하기 }
< toSrting >
const today = new Date(2000, 9, 10, 22);
console.log(today.toString()); // Tue Oct 10 2000 22:00:00 GMT+0900 (한국 표준시)
< toDateString >
< toLocaleString, toLocaleDateString >
const today = new Date(2000, 9, 10, 22);
console.log(today.toLocaleString()); // 2000. 10. 10. 오후 10:00:00
console.log(today.toLocaleDateString()); // 2000. 10. 10.
{ Date 객체 응용하기 }
< n월씩 이동하기 >
function moveMonth(date, moveMonth) { // ①
const curTimestamp = date.getTime(); // ②
const curMonth = date.getMonth(); // ③
const resDate = new Date(curTimestamp); // ④
resDate.setMonth(curMonth + moveMonth); //⑤
return resDate;
}
const dateA = new Date("2000-10-10");
console.log("A: ", dateA); // A : Tue Oct 10 2000 09:00:00 GMT+0900 (한국 표준시)
const dateB = moveMonth(dateA, 1);
console.log("B: ", dateB); // B : Fri Nov 10 2000 09:00:00 GMT+0900 (한국 표준시)
const dateC = moveMonth(dateA, -1);
console.log("C: ", dateC); // C : Sun Sep 10 2000 09:00:00 GMT+0900 (한국 표준시)
④ 변수 resDate를 만들고 새로운 Date 객체를 생성합니다. Date 객체를 만들면서 ②에서 구한 타 임 스탬프값(curTimestamp)을 인수로 전달합니다. 결과적으로 변수 resDate에는 date 객체와 동일한 타임스탬프값이 들어 있는 Date 객체가 저장됩니다.
⑤ 변수 resDate에 저장된 Date 객체에서 setMonth 메서드를 호출해 기존 월에 moveMonth만큼 더 한 월을 새로운 월로 저장합니다. 결론적으로 이 함수를 호출하면 moveMonth만큼 월을 앞으로 또는 뒤로 이동시킵니다.
< 배열에서 이번 달에 해당하는 날짜만 필터링하기 >
function filterThisMonth(pivotDate, dateArray) { // ①
const year = pivotDate.getFullYear();
const month = pivotDate.getMonth();
const startDay = new Date(year, month, 1, 0, 0, 0, 0); // ②
const endDay = new Date(year, month + 1, 0, 23, 59, 59); // ③
const resArr = dateArray.filter(
(it) =>
startDay.getTime() <= it.getTime() && // ④
it.getTime() <= endDay.getTime()
);
return resArr;
}
const dateArray = [
new Date("2000-10-1"),
new Date("2000-10-31"),
new Date("2000-11-1"),
new Date("2000-9-30"),
new Date("1900-10-11")
];
const today = new Date("2000-10-10/00:00:00"); // 오늘은 2000년 10월 10일이라고 가정합니다.
const filteredArray = filterThisMonth(today, dateArray);
console.log(filteredArray);
// 0: Sun Oct 01 2000 00:00:00 GMT+0900 (한국 표준시)
// 1: Tue Oct 31 2000 00:00:00 GMT+0900 (한국 표준시)
③ 이번 달의 가장 늦은 시간은 다음 달 0일의 23시 59분 59초(이번 달의 가장 마지막 날을 의미)로 설정해 구합니다.
④ filter 메서드를 이용해 dateArray에서 이번 달에 속하는 요소만 필터링합니다. 서로 다른 Date 객체를 비교할 때는 getTime 메서드로 타임스탬프를 기준으로 비교합니다. 특정 Date 객체가 더 크다는 것은 이 객체가 더 미래에 있는 시간이라는 뜻입니다.
Q. 왜 이달의 가장 늦은 시간이 다음 달 0일 23시 59분 59초일까?
Date 객체에서 date 즉 일을 0으로 설정하면 해당 월 바로 이전 월의 마지막 날을 의미한다. 즉 2000년 10월 0일은 2000년 9월의 마지막 날이다.
< 동기와 비동기 >
setTimeout(function () { ①
console.log("1번!");
}, 3000);
console.log("2번!");
// 2번!
// 1번!
① 함수 setTimeout은 두 번째 인수로 전달된 시간(밀리초)만큼 기다린 다음, 첫 번째 인수로 전달 한 콜백 함수를 실행합니다. 따라서 이 코드에서는 3초(3000밀리 초)만큼 기다린 다음 콜백 함수를 실행합니다.
다음과 같이 화살표 함수를 이용하면 더 간결하게 작성할 수 있다.
setTimeout(() => { ①
console.log("1번!");
}, 3000);
console.log("2번!"); ②
// 2번!
// 1번!
function orderCoffee(coffee, time) { ①
setTimeout(() => {
console.log(`${coffee} 제조 완료`);
}, time);
}
orderCoffee("달콤한 커피", 4000);
orderCoffee("레몬 티", 2000);
orderCoffee("시원한 커피", 3000);
// 레몬 티 제조 완료
// 시원한 커피 제조 완료
// 달콤한 커피 제조 완료
< 콜백 함수로 비동기 처리하기 >
다음 예제의 함수 double은 1초를 기다린 다음 전달한 인수에 2를 곱해 콘솔에 출력한다.
function double(num) {
setTimeout(() => {
const doubleNum = num * 2;
console.log(doubleNum);
}, 1000);
}
double(10); // 20
만약 함수 double의 결과를 반환하게 하려면 어떻게 해야 할까?
function double(num) {
return setTimeout(() => {
const doubleNum = num * 2;
return doubleNum; ①
}, 1000);
}
const res = double(10);
console.log(res);
// 알 수 없는 숫자
다음과 같이 콜백 함수의 인수로 2를 곱한 결괏값을 전달하면, 간단하게 비동기 작업의 결괏값을 반환값으로 사용할 수 있다.
function double(num, cb) {
setTimeout(() => {
const doubleNum = num * 2;
cb(doubleNum); // ②
}, 1000);
}
double(10, (res) => { // ①
console.log(res);
});
console.log("마지막"); // ③
// 마지막
// 20
① 함수 double을 호출하며 두 번째 인수로 화살표 함수로 만든 콜백 함수를 전달합니다. 콜백 함수는 함수 double의 매개변수 cb에 저장되며, 호출되면 인수로 전달한 값을 콘솔에 출력합니다.
② 비동기 작업이 완료되면 콜백 함수를 호출해 연산의 결괏값을 인수로 전달합니다.
-> 콜백 함수를 이용하면 비동기 작업의 결괏값을 사용할 수 있다.
< 프로미스 객체를 이용해 비동기 처리하기 >
const promise = new Promise(실행 함수); ①
const promise = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log("안녕");
}, 500);
});
// 안녕
다음은 매개변수 resolve를 호출하여 작업 상태를 성공 상태로 변경하는 예이다.
const promise = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve("성공");
}, 500);
});
만약 결괏값을 비동기 작업이 아닌 곳에서 이용하려면 다음과 같이 프로미스 객체의 then 메서드를 이용한다.
const promise = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve("성공");
}, 500);
});
promise.then(function (res) { ①
console.log(res);
});
// 성공
① then 메서드를 호출하고 인수로 콜백 함수를 전달합니다. 이 콜백 함수는 비동기 작업이 성공했을 때, 즉 실행 함수가 resolve를 호출했을 때 실행됩니다.
-> 실행 함수에서 0.5초 기다린 다음 resolve를 호출하고 인수로 "성공"을 전달한다.
const promise = new Promise(function (resolve, reject) {
setTimeout(() => {
reject("실패");
}, 500);
});
promise.then(function (res) {
console.log(res);
});
promise.catch(function (err) { ①
console.log(err);
});
// 실패
① 실행 함수에서 reject를 호출하여 이 작업이 실패했음을 알리고 인수로 “실패”를 전달합니다.
② 비동기 작업이 실패했으므로 then 메서드에 인수로 전달한 콜백 함수는 실행되지 않습니다.
이때 then 메서드에 전달한 콜백 함수는 실행되지 않는다.
작업이 실패했을 때 실행할 콜백 함수를 설정하려면 다음과 같이 catch 메서드를 사용해야 한다.
const promise = new Promise(function (resolve, reject) {
setTimeout(() => {
reject("실패");
}, 500);
});
promise.then(function (res) {
console.log(res);
});
promise.catch(function (err) { ①
console.log(err);
});
// 실패
-> 이처럼 프로미스의 then과 catch 메서드를 이용하면 작업이 성공하거나 실패했을 때 실행할 콜백 함수를 별도로 설정할 수 있다.
1. slice 메서드는 원본 배열을 수정하지 않지만, concat 메서드는 원본 배열을 수정한다. ( O / X )
2. indexOf는 자료형이 달라도 같은 값으로 평가한다. (O / X )
3. sort 메서드는 새로운 배열을 반환하는 것이 아니라, 기존 배열 요소를 다시 정렬한다. (O / X )
4. 협정 세계시에서 시간의 시작되는 순간을 말해보자.
5. Date 객체에서 날짜 요소 얻기에서 연도를 반환받기 위해서는 ( ) 메서드를 이용한다.
6. getDay 메서드에서 목요일은 숫자 몇으로 반환될까?
7. Date 객체 출력하는 메서드 중 '현지화'된 날짜와 시간을 모두 반환하는 메서드의 이름을 말해보자.
1. 다음 코드의 결과를 말해보자.
let arr = [1, 3, 5, 7, 1];
console.log(arr.indexOf(7, 9));
2. reduce 메서드를 이용하여 1부터 5까지 더해지는 코드를 짜보아라.
x / x / o / 1970년 1월 1일 0시 0분 0초 / getFullYear / 4 / toLocaleString
-1
let arr = [1, 2, 3, 4, 5];
let result = arr.reduce((acc, item) => acc + item, 0);
console.log(result); // 15
출처: 이정환, 『한 입 크기로 잘라먹는 리액트』, 프로그래밍인사이트(2023), 2-5~2-9장.
Editor: yunseul
[리액트 스타터2] 5장. 리액트의 기본 기능 다루기(2) (0) | 2023.11.10 |
---|---|
[리액트 스타터2] 5장. 리액트의 기본 기능 다루기(1) (1) | 2023.11.03 |
[리액트 스타터2] 4장. 리액트 시작하기 (0) | 2023.10.13 |
[리액트 스타터2] 3장. Node.js (0) | 2023.10.13 |
[리액트 스타터2] 1장. 자바스크립트 기초 (0) | 2023.09.29 |