JS 데이터. 배열, 객체 [패스트캠퍼스 챌린지 06일차]
배열
~번째 : index
인덱스 숫자를 넣어 조회하는 걸 indexing이라고 함
- 배열 데이터 내 각각의 데이터들을 element(요소)라고 함.
- 공식 명칭은 element이지만, html과의 구분을 위해 배열의 item이라고도 함
const numbers = [1, 2, 3, 4]
const fruits = ['Mango', 'Kiwi', 'Cherry']
console.log(numbers)
/*
(4) [1, 2, 3, 4]
0: 1
1: 2
2: 3
3: 4
length: 4
[[Prototype]]: Array(0)
*/
console.log(numbers[1]) //2
console.log(fruits)
/*
(3) ['Mango', 'Kiwi', 'Cherry']
0: "Mango"
1: "Kiwi"
2: "Cherry"
length: 3
[[Prototype]]: Array(0)
*/
console.log(fruits[2]) // Cherry
.length
배열 데이터가 가지고 있는 아이템 갯수 반환
- length를 이용해 배열 데이터의 내용이 채워져 있는지 그렇지 않은지를 확인하는 경우가 굉장히 많으니 기억해두기
const numbers = [1, 2, 3, 4]
const fruits = ['Mango', 'Kiwi', 'Cherry']
console.log(numbers.length)//4
console.log(fruits.length)//3
console.log([1, 2].length)//2
console.log([].length) //0
.concat()
두 개의 배열 데이터를 병합해서 새로운 배열 데이터를 그 자리에 반환해주는 메소드
원본의 배열 데이터가 손상되지 않음
- 이게 뭐가 중요하냐 싶지만, 원본의 배열이 수정되냐 안되냐는 배열 API를 공부할 때 주의해야 할 내용임
const numbers = [1, 2, 3, 4]
const fruits = ['Mango', 'Kiwi', 'Cherry']
console.log(numbers.concat(fruits))
/*
(7) [1, 2, 3, 4, 'Mango', 'Kiwi', 'Cherry']
0: 1
1: 2
2: 3
3: 4
4: "Mango"
5: "Kiwi"
6: "Cherry"
length: 7
*/
// 아래 출력값은 원본이 손상되지 않았음을 보여줌
console.log(numbers)//(4) [1, 2, 3, 4]
console.log(fruits)//(3) ['Mango', 'Kiwi', 'Cherry']
.forEach()
배열 데이터가 가지고 있는 아이템의 개수만큼 콜백 함수가 반복하며 실행
콜백? 메소드의 인수로 사용하는 함수를 콜백이라고 함
배열 데이터에서 사용할 수 있는 반복적으로 동작하는 메소드들은 기본적으로 인수로 콜백을 사용 가능
배열 아이템, 인덱스, 원본의 배열 데이터를 순서대로 매개 변수로 제공하고 있음(여기 정리 다시...꽥)
여러 배열의 메소드들에서 같은 방식으로 사용 가능
const fruits = ['Mango', 'Kiwi', 'Cherry']
fruits.forEach(function (element, index, array) {
console.log(element, index, array)
})
/*
Mango 0 (3) ['Mango', 'Kiwi', 'Cherry']
Kiwi 1 (3) ['Mango', 'Kiwi', 'Cherry']
herry 2 (3) ['Mango', 'Kiwi', 'Cherry']
*/
- 매개변수 이름 자유롭게 작성 가능
// element 대신 item이라고 써도 됨.
fruits.forEach(function (item, index, array) {
console.log(item, index, array)
})
// s를 떼고 fruit로 해도 됨
fruits.forEach(function (fruit, index, array) {
console.log(fruit, index, array)
})
- array라는 매개변수는 fruits를 지칭하는데, 쓰는 일 별로 없으니 없애도 됨
fruits.forEach(function (fruit, index) {
console.log(fruit, index)
})
- index를 i로 축약해서 사용 가능
//index = i
fruits.forEach(function (fruit, i) {
console.log(fruit, i)
})
.map()
forEach와 map의 차이점
map이라는 메소드는
인수로 사용하는 콜백의 내부에서 반환하는 데이터를 가지고
그 데이터들을 모아 놓은 새로운 배열을 만들어서 반환.
이것이 forEach와의 차이왜 이해 못하냐...
map이라는 메소드는, 콜백에서 반환된 특정한 데이터를 기준으로, 이 데이터들의 새로운 배열을 반환하고, 반환된 값을 변수에 할당이정도면 이해하겠찌?
forEach는 아이템의 갯수만큼 콜백 함수를 반복하는데, 따로 반환되는 값은 없음.
map도 아이템 갯수만큼 콜백을 반복하는데, 그 콜백 내부에서 리턴 키워드를 통해 반환한 데이터를 새로운 배열로 만들어서 사용할 수 있음.
- 먼저 forEach부터 보자
const fruits = ['Mango', 'Kiwi', 'Cherry']
const a = fruits.forEach( function (fruit, index) {
console.log(`${fruit}-${index}`)
})
/*
Mango-0
Kiwi-1
Cherry-2
*/
console.log(a)
//undefined 어디서 왔는지 설명해주셨는데 이해 못함 forEach이긴 함...
- map 차례
const b = fruits.map(function (fruit, index) {
return `${fruit}-${index}`
})
console.log(b) //(3) ['Mango-0', 'Kiwi-1', 'Cherry-2']
- ⭐️아래와 같은 방법 굉장히 많이 사용하니까 익숙해져야 함
const fruits = ['Mango', 'Kiwi', 'Cherry']
/*
const b = fruits.map(function (fruit, index) {
return {} //객체 리터럴 방식으로 작성
})
*/
const b = fruits.map(function (fruit, index) {
return {
id: index,
name: fruit
}
})
console.log(b)
/*
(3) [{…}, {…}, {…}]
0: {id: 0, name: 'Mango'}
1: {id: 1, name: 'Kiwi'}
2: {id: 2, name: 'Cherry'}
length: 3
- 노멀 함수 → 화살표 함수
//내용에는 변함 없음.
//앞으로는 화살표 함수 사용 권장
const number = [1, 2, 3, 4]
const fruits = ['Mango', 'Kiwi', 'Cherry']
const a = fruits.forEach((fruit, index) => {
console.log(`${fruit}-${index}`)
})
console.log(a)
const b = fruits.map((fruit, index) => ({
id: index,
name:fruit
}))
//객체데이터니까 소괄호로 한번 감싸서 일케일케 ({ 내용들 })
console.log(b)
.filter()
filter라는 메소드는 콜백 함수에서 반환되는 값이 true인 경우에만
해댕하는 아이템의 데이터를 새로운 배열에 하나씩 넣음
map과 filter의 차이
차이점와 공통점
차이점
map : 메소드가 사용된 배열 데이터의 갯수만큼 반복적으로 내용이 동작하면서 새롭게 반환된 배열 데이터도 원래 배열 데이터가 가진 아이템의 갯수만큼 똑같이 만들어짐
filter : 필터링을 해서 일부 내용들을 걸러내고 새로운 배열을 만드는 개념.
새로 만들어진 배열이 원본의 갯수랑 다를 수도 있음공통점
map과 filter 둘 다 원본 데이터를 훼손하지 않음
원본 데이터에 영향 없이 새로운 데이터를 반환하는 배열 메소드
const numbers = [1, 2, 3, 4]
const fruits = ['Banana', 'Kiwi', 'Cherry']
//map 메소드
const a = numbers.map(number => {
return number < 3
})
console.log(a) //[true, true, false, false]
//filter 메소드
const b = numbers.filter(number => {
return number < 3
})
console.log(b) //[1, 2]
- return 키워드랑 { 중괄호 } 생략 가능. 깔끔깔끔
const a = numbers.map(number => number < 3)
const b = numbers.filter(number => number < 3)
.find()
배열 데이터 안에서 콜백 조건에 맞는 특정한 아이템을 찾을 때 사용
제일 먼저 찾아진 아이템을 반환하고 거기서 콜백 함수의 반복은 종료됨
걍 쉽게 말해서, 뭐 하나 찾으면 거기서 멈추고 그 값 하나만 반환함
정규표현식의 통해 B로 시작하는 문자데이터를 찾는데,
정규표현식의 내용과 fruit의 내용이 일치하면 불리언 true가 나오고 아니면 false 나옴
true가 반환됐을 때 거기서 아이템 반복하는 건 종료.( 여기서 중요한 건 find 메소드가 어떻게 동작하는지 기본적인 원리를 이해하는 것이지,
정규표현식을 쓴다는 게 중요한 게 아님)
const fruits = ['Watermelon','Blueberry', 'Cherry']
const a = fruits.find(fruit => /^B/.test(fruit)) // 정규표현식 /^B/
console.log(a) // Blueberry
.findIndex()
제일 첫째로 찾아진 조건에 맞는 아이템의 인덱스 번호를 반환하는 메소드
- 이녀석 굉장히 많이 사용함
- 인덱스는 뭐다? zero based
const fruits = ['Watermelon','Blueberry', 'Cherry']
const a = fruits.findIndex(fruit => /^C/.test(fruit)
)
console.log(a) // 2
.includes
인수로 사용된 특정한 데이터가 배열 데이터 안에 포함되는지 아닌지 확인하는 메소드
반환은 불리언 데이터
const numbers =[1, 2, 3, 4]
const fruits =['Apple', 'Banana', 'Cherry']
const a = numbers.includes(3)
console.log(a) // true
const b = fruits.includes('Donut')
console.log(b) // false
.push()
.unshift()
push : 배열 데이터 맨 뒤에 삽입
unshift : 배열 데이터 맨 앞에 삽입
- 🍄 주의! 🍄 원본 배열 데이터가 수정됨.
- push 굉장히 많이 사용
- unshift도 꽤 사용함
const numbers = [1, 2, 3, 4]
numbers.push(5)
console.log(numbers) // [1, 2, 3, 4, 5]
numbers.unshift(0)
console.log(numbers) // [0, 1, 2, 3, 4, 5]
.reverse()
🍄 주의! 🍄 원본 배열 데이터가 수정됨.
const numbers = [1, 2, 3, 4]
const fruits = ['Apple', 'Banana', 'Cherry']
numbers.reverse()
fruits.reverse()
console.log(numbers) //[4, 3, 2, 1]
console.log(fruits) //['Cherry', 'Banana', 'Apple']
.splice()
배열 데이터에서 특정한 아이템을 지울 때 많이 사용
아이템 제거하는 용도로 사용하는데,
그 자리에 새로운 아이템을 끼워 넣는 용도로도 사용
- (인덱스, 제거 갯수)
- (인덱스, 제거 갯수, 삽입할 내용)
🍄 주의! 🍄 원본 배열 데이터가 수정됨.
- (인덱스 어디서 시작할래, 몇개를 지울래)
const numbers = [1, 2, 3, 4]
numbers.splice(2, 1)
console.log(numbers) //[1, 2, 4]
- 두번째 인수에 0을 넣어볼까?
const numbers = [1, 2, 3, 4]
numbers.splice(2, 0)
console.log(numbers) //[1, 2, 3, 4]
- 세번째 인수 추가요!
(인덱스 어디서 시작할래?, 몇개를 지울래?, 뭘 끼워넣을래?)
const numbers = [1, 2, 3, 4]
numbers.splice(2, 0, 999)
// 인덱스 2번에서 아이템 0개 지우고 999라는 숫자 데이터를 끼워 넣어라
console.log(numbers)
//[1, 2, 999, 3, 4] 인덱스 2번 자리에 999가 들어가 있네
- 세번째 인수 또다른 예시
const numbers = [1, 2, 3, 4]
numbers.splice(2, 1, 99)
// 인덱스 2번에서 시작할건데, 아이템 하나 지우고, 인덱스 2번에 99 삽입이요
console.log(numbers) // [1, 2, 99, 4]
- 예시 하나 더!
const fruits = ['Watermelon','Blueberry', 'Cherry']
// 블루베리랑 체리 사이에 키위 넣고 싶어
fruits.splice(2, 0, 'Kiwi')
console.log(fruits)
//['Watermelon', 'Blueberry', 'Kiwi', 'Cherry']
객체
Object.assign()
Object.assign() 메소드는 출처 객체로부터 모든 열거할 수 있는(enumerable) 하나 이상의 속성(own properties)들을 목표 객체로 복사합니다. 이는 수정된 목표 객체를 반환합니다.
대상 객체 = 목표 객체
- Object의 assign이란 메소드는
첫번째 인수로 들어간 target이란 목표/대상 객체에
두번째 인수로 들어간 sourse라는 출처 객체를 병합 - 그렇게 병합된 target이란 목표/대상 객체를 returnedTarget에 반환
- returnedTarget이란 변수는 곧 기존의 target과 실제로 같은 객체 데이터임
- 둘 다 출력해 보면,
target과 sourse가 합쳐진 동일한 객체 데이터가 출력됨
- Object의 assign이란 메소드는
Object.assign()
assign은 Object라는 전역 객체에 직접적으로 사용하는 정적 메소드
const userAge = {
// property 자리에 값이 들어가 있는 걸 키 밸류 형태라고 함 key: value
name: 'Kaki',
age: 89
}
const userEmail = {
name: 'Kaki',
email: 'kaki@tree.com'
}
const target = Object.assign(userAge, userEmail)
console.log(target)
console.log(userAge)
// 위에 두 녀석의 값은 동일함 {name: 'Kaki', age: 89, email: 'kaki@tree.com'}
// 일치 연산자로 확인해볼까?
console.log(target === userAge) // true
생긴 게 똑같다고 일치 연산자로 true가 나오는 건 아냐
이유 설명
참조형 데이터의 특징임
{ 객체 }, [ 배열 ], function → 이런 애들이 참조형 데이터
메모리에 있는 특정 주소를 참조만 해서 사용한다는... 그런...JS의 불변성과 가변성 시간에 자세히 다뤄보자구
-
첫번째 예시는 일치 연산자로 true가 나옴
이름이 달라도 저장된 메모리 위치가 같다는...
결과적으로 같은 장소를 바라보고 있기 때문에 일치 연산자가 ture를 내놓음
-
두번째 예시는 일치 연산자로 false가 나옴
생긴 건 똑같지만 서로 다른 메모리 주소를 바라보고 있기 때문에 다른 녀석이라고 하는 거임
const a = { k: 123 }
const b = { k: 123 }
console.log(a === b) // false
// 똑같아 보이는데 다르다고 뜨네? 이유는 아래에
원본 데이터 그대로 두고 새로운 객체 데이터로 만들고 싶으면 어떻게 하나여?
방법은 간단
목표/대상 객체(1st 인수) 자리에 빈 객체 리터럴 작성
→ 아까 목표 객체 자리에 있던 애는 출처 객체 자리로 밀려남
→ 이제 두 개가 된 출처 객체들이 빈 객체 데이터로 들어가고
→ 목표 객체는 뒤에 두 녀석들의 속성값을 가지고 변수로 반환
요런 방식 굉장히 많이 사용
const userAge = { name: 'Kaki', age: 89 } const userEmail = { name: 'Kaki', email: 'kaki@tree.com' } const target = Object.assign({}, userAge, userEmail) console.log(target) // {name: 'Kaki', age: 89, email: 'kaki@tree.com'} console.log(userAge) // {name: 'Kaki', age: 89} console.log(target === userAge) //false
-
'복사본' 이런 느낌으로도 많이 사용
```jsx
const userAge = {
name: 'Kaki',
age: 89
}
const target = Object.assign({}, userAge)console.log(target) // {name: 'Kaki', age: 89}
console.log(userAge) // {name: 'Kaki', age: 89}console.log(target === userAge) // false
/*
변수 target이 userAge의 복사본인 것 마냥 사용 가능
둘은 다른 메모리 위치를 사용
그래서 false 나옴 /
```Object.keys()
-
Object.keys()
- property들이 배열 데이터로 저장됨
const user = {
// key:value 키 밸류
name: 'Kaki',
age: 89,
email: 'kaki@tree.com'
}
const test = Object.keys(user)
// 변수 user의 속성들을 test에 할당
// 변수 test에는 뭐가 들어있나 볼까?
console.log(test) // ['name', 'age', 'email']
- 객체 데이터에서 사용할 수 있는 인덱싱 방법
- 객체 데이터에서는
변수명.속성이름
변수명['속성이름'] 요것도 있음
- 배열 데이터에서는
변수명[인덱스숫자]
console.log(user['email']) // kaki@tree.com
- 객체 데이터를 변수명['속성이름'] 이렇게 문자 데이터로 작성하는 게 언제 효과적이냐!
- 아래 코드에서 효과적임
const user = {
name: 'Kaki',
age: 89,
email: 'kaki@tree.com'
}
const test = Object.keys(user)
console.log(test) // ['name', 'age', 'email']
const values = test.map (item => user[item])
/* 요기 item 매개변수 자리에 변수 test의 값들이 하나씩 들어갈거임.
총 세 번 콜백이 실행될거고, 결과물들은 변수 values로 들어감
아래에 values 출력값
*/
console.log(values) //['Kaki', 89, 'kaki@tree.com']
https://bit.ly/37BpXiC
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
#직장인인강 #직장인자기계발 #패스트캠퍼스 #패스트캠퍼스후기 #패캠챌린지 #한번에끝내는프론트엔드개발초격차패키지Online