객체와 배열
구분 | 객체 | 배열 |
구조 | 프로퍼티 키와 값 | 인덱스와 요소 |
값의 참조 | 프로퍼티 키 | 인덱스 |
값의 순서 | X | O |
length 프로퍼티 | X | O |
배열
자료구조에서 말하는 배열은 동일한 크기의 메모리 공간이 빈틈없이 연속적으로 나열된 자료구조를 말한다.
즉, 배열의 요소는 하나의 데이터 탕비으로 통일되어 있으며 연속적으로 인접해 있다.
-> 이를 밀집배열(dense array)라고 한다
- 검색 대상 요소의 메모리 주소 = 배열의 시작 메모리 주소 + 인데스 * 요소의 바이트 수
메모리 주소가 100이고 각 요소가 8바이트면 아래처럼 계산된다
100 + 0*8 =100
100 + 1*8 =108
배열의 요소가 연속적으로 이어져 있지 않은 배열을 희소 배열(sparse array)라고 한다
자바스크립트의 배열은 일반적인 배열의 동작을 훙내 낸 특수한 객체
인덱스를 나타내는 문자열을 프로퍼티 키로 가지며, length 프로퍼티를 갖는 특수한 객체다
자바스크립트에서 사용할 수 있는 모든 값은 객체의 프로퍼티 값이 될 수 있으므로 어떤 타입의 값이라도 배열의 요소가 될 수 있다
- 자바스크립트 배열은 해시 테이블로 구현된 객체
-> 인덱스로 요소에 접근 ( 일반적인 배열 > JS 배열)
-> 특정 요소 검색,삭제 ( 일반적인 배열 < JS 배열)
length
const arr=[1,2,3,4,5]
arr.length=3
console.log(arr); //[1,2,3]
값을 늘리면 length 프로퍼티의 값은 변경되지만 실제로 변하진 않는다
const arr1=[1]
arr.length=3;
console.log(arr1.length); //3
console.log(arr1); //[1,empty*2]
희소배열
const sparse=[,2, ,4]
sparse.length => 4
console.log(sparse) // [empty,2,empty,4]
희소배열의 length는 실제 요소 개수보다 언제나 크다. -> 사용하지 않는 것을 추천
*유사 배열 객체
유사 배열 객체는 배열과 비슷한 동작이 가능하다
const arrayLike={
'0':'apple',
'1':'banana',
'2':'orange',
length:3
}
for (let i = 0; i < arrayLike.length; i++) {
console.log(arrayLike[i]);
}
요소 추가시 정수 이외의 값을 인덱스처럼 사용하면 프로퍼티가 생성된다
const arr=[]
arr.bar=4;
arr[1.1]=2
console.log(arr) // [bar:4,'1.1':2]
책에서 소개하는 다양한 메서드는 MDN에서 확인가능하고 알고리즘은 따로 정리해 두겠다
배열 고차 함수
고차 함수는 외부 상태의 변경이나 가변데이터를 피하고 불변성을 지향하는 함수형 프로그래밍에 기반을 두고 있다
-조건문과 반복문 제거 , 변수의 사용 억제, 순수함수를 통해 부수 효과를 최대한 억제 -> 프로그래밍의 복잡성,가독성
-> 안정성을 높이려는 노력
Array.prototype.sort
[!] 숫자 요소를 정렬할 때는 sort메서드에 정렬 순서를 정의하는 비교 함수를 인수로 전달해야 한다
const points=[40,100,1,5,2,25,10]
//숫자 배열의 오름차순 정렬, 비교 함수의 값이 0보다 작으면 a를 우선으로 정렬
points.sort((a,b)=>a-b)
//숫자 배열의 내림차순 정렬, 비교 함수의 값이 0보다 작으면 b를 우선으로 정렬
points.sort((a,b)=>b-a)
객체를 요소로 갖는 배열을 정렬하는 예제
const todos=[
{id:4,content:'JavaScript'},
{id:1,content:'HTML'},
{id:2,content:'CSS'}
]
function compare(key){
return (a,b)=>(a[key]>b[key]? 1: (a[key] < b[key] ? -1 :0 ))
}
todos.sort(compare('id'))
console.log(todos);
foreach 메서드는 단순히 반복문을 대체하기 위한 고차 함수
-원본 배열을 변경할 수 없지만 콜백 함수를 통해 변경가능
const numbers=[1,2,3]
numbers.forEach((item,index,arr)=>{arr[index]= item**2})
console.log(numbers); // [1,4,9]
forEach메서드의 콜백 함수 내부에서 this로 사용할 객체 전달
class Numbers{
num=[];
muti(arr){
arr.forEach(function(){
//TypeError : this는 undefined
this.num.push(i*i)
})
}
}
const numbers=new Numbers();
numbers.muti([1,2,3])
화살표함수를 통해 상위 스코프의 this를 자연스럽게 참조
class Numbers{
num=[];
muti(arr){
arr.forEach(i=>this.num.push(i*i))
}
}
const numbers=new Numbers();
numbers.muti([1,2,3])
console.log(numbers.num); //[ 1, 4, 9 ]
map 메서드는 요소값을 다른 값으로 매핑하는 새로운 배열을 생성하기 위한 고차 함수
class Prefixer{
constructor(prefix){
this.prefix=prefix
}
add(arr){
return arr.map(i=>this.prefix+i)
}
}
const prefixer=new Prefixer('hi-')
console.log(prefixer.add(['new','hello'])); //[ 'hi-new', 'hi-hello' ]
map 메서드가 생성하여 반환하는 새로운 배열의 length 프로퍼티 값은 map 메서드를 호출한 배열의 length 프로퍼티 값과 반드시 일치한다. 즉, 1:1 매핑한다
filter 메서드를 사용해 검색 및 삭제
class Users{
constructor(){
this.users=[
{id:1,name:'Lee'},
{id:2,name:'Kim'}
]
}
findById(id){
return this.users.filter(user=>user.id===id)
}
remove(id){
this.users=this.users.filter(user=>user.id!==id)
}
}
const users=new Users();
let user=users.findById(1)
console.log(user); //[ { id: 1, name: 'Lee' } ]
users.remove(1)
console.log(users); //Users { users: [ { id: 2, name: 'Kim' } ] }
reduce 메서드는 하나의 결과값을 반환한다
배열의 모든 요소를 순회하며 하나의 결과값을 구해야 하는 경우에 사용한다
reduce 메서드를 호출할 때는 언제나 초기값을 전달하는 것이 안전하다
const products=[
{id:1,price:100},
{id:2,price:200},
{id:3,price:300},
]
1번째 순회 때 acc는 {id:1,price:100} cur은 {id:2,price:200}
2번째 순회 때 acc는 300, cur은 {id:3,price:300}
3번째 순회 때 acc값이 숫자기 때문에 acc.price는 undefined가 된다
const total=products.reduce((acc,cur)=>acc.price+cur.price)
console.log(total); //NaN
아래처럼 초기값을 전달하면
acc는 0, cur은 {id:1,price:100}
acc는 100, cur은 {id:2,price:200}
acc는 300, cur은 {id:3,price:300}
const products=[
{id:1,price:100},
{id:2,price:200},
{id:3,price:300},
]
const total=products.reduce((acc,cur)=>acc+cur.price,0)
console.log(total); //600
나머지 메서드는 한번씩 읽고 넘어가자
'JavaScript' 카테고리의 다른 글
이터러블 (0) | 2022.06.29 |
---|---|
RegExp (0) | 2022.06.29 |
ES6 함수의 추가 기능 (0) | 2022.06.22 |
클래스 (0) | 2022.06.19 |
클로저(Closure) (0) | 2022.06.13 |