자바스크립트에서 가장 중요한 데이터 구조, 객체와 배열에 대해 정리😋
자바스크립트에서 대부분의 자료구조
는 배열과 객체이다. 서버와 통신을 통해 받아오는 데이터도 JSON 형태로 객체
와 배열
로 이루어져 있다. 그러므로 이 두가지의 핵심 자료구조를 정확하게 알고 사용하는 것이, 프론트엔드 또는 node
베이스 서버를 다루는 개발자들에겐 요구되어지는 역량이다🙄. 차례대로 살펴보자.
자바스크립트에선 여덟가지 자료형이 존재. 그 중 일곱 개는 원시형
데이터로 오직 하나의 데이터만 담는다. 객체는 키(key)
와 값(value)
으로 구성된 프로퍼티
를 여러 개 넣을 수 있는데 키엔 문자형과 심볼(Symbol)
, 값엔 모든 자료형이 허용됨.
객체를 가르키는 변수엔 그 객체의 주소 값
을 담음
const obj = {hi: '안녕하세요', bye: '안녕히가세요'};
// obj엔 객체의 주소 값이 들어감.
const number = 1;
// number엔 1이라는 데이터 값이 들어감
객체 선언 방식은 두 가지.
// 객체 리터럴 문법
const obj = {name: 'wabbang', age: 29};
// 객체 생성자 문법
const obj2 = new Object();
프로퍼티 삭제는 delete
연산자를 사용.
키가 띄어쓰기가 있는 문자열일 경우 대괄호 표기법으로 표현해야 합니다.
let user ={
name: "John",
age: 10,
"likes foods": true
};
user.likes foods = false // error 띄어쓰기가 있는 키는 점 표기법으로 불러올 수 없음
user.["likes foods"] = false // ok 대괄호 표기법!
객체의 키를 대괄호[]
로 둘러싸 계산된 프로퍼티를 만들 수 있음
let wanted = propmt('무엇을 원해여??', '장난감');
let person = {
[wanted]: "구매하기"
};
객체는 참조
에 의해 복사. ==
, ===
연산자가 같은 결과를 가져온다. 다른 변수에 객체를 할당하면 같은 주소값
을 가지고 복사가 됨. 복사가 아닌 독립적으로 복제
된 객체를 만들기 위해선 for in
구문을 이용하거나, Object.assign 함수를 이용하자
let user = {
name: 'dudu',
age: 15,
};
let userHobby ={
baseball: true,
football: false
};
let clone ={}; // 빈 객체를 할당
for (let key in user) {
clone[key] = user[key]; // user 프로퍼티를 전부 복사해 넣음
}
// or
Object.assign(clone, user, userHobby)
// 첫번째 인수 clone에 이 후 나머지 인수 객체들의 프로퍼티가 추가됨)
객체의 key
에 또 다시 객체가 들어 올 수 있다.
let mom = {
age: 30,
firstchild: {
name: 'dudu',
age: 1 // 이렇게 객체 안의 객체가 있는 것이 중첩 객체
}
}
이런 중첩 구조를 가지는 객체는 키를 복사할 경우 키에 담긴 객체 주소 값이 복사 되기 때문에 같은 객체
를 공유
한다.
이처럼 중첩된 객체를 복사할 경우엔 Object.assing()을 사용하지 말고 자바스크립트 라이브러리 lodash
의 메서드인 _.cloneDeep(obj)
를 사용해야 함다.
🙄 깊은 복사와 얕은 복사로 유명한 객체를 복제하는 방법은 나중에 따로 구체적인 블로깅을 할 생각입니다.
키를 사용해 식별할 수 있는 값을 담은 컬렉션은 객체
라는 자료구조, 키가 아닌 순서에 따라 값을 담아두는 자료구조를 배열이라고 한다. 인덱스
를 통해 값을 가져올 수 있는데, 객체와 함께 가장 많이 사용되는 중요한 자료구조라고 할수 있겠다!
배열의 선언도 객체와 마찬가지로 2가지로 가능. 리터럴
, new
let arr = new Array();
let arr2 = [];
배열은 인덱스
를 통해 값을 가져오기도 하고 값을 변경하기도 한다.
let fruits = ['사과', '바나나', '딸기', '포도'];
fruits[0] // ==> '사과'
fruits[0] = "애플워치" // 사과 ==> 애플워치로 변경
fruits[2] = {name: "파인애플", color: "노랑"} // 딸기 ==> 객체,
// 배열의 값으로 객체도 받을 수 있음
배열은 length를 통해 배열의 길이를 알 수 있다. 예를 들어 4가지 값이 들어있는 배열의 length는 4이다. index는 각 값이 담겨있는 key인데, 시작하는 숫자가 1
이 아니고 0
이다.
배열의 반복은 객체와 달리 for in
구문을 쓰는것을 지양해야함. 모든 키 값을 대상으로 반복문을 돌기 때문에 불필요한 프로퍼티
도 포함 시킴. 대신 for of
문을 통해 순회하거나 기본적인 반복문 사용.
let arr = ["사과", "오렌지", "배"];
for (let i = 0; i < arr.length; i++) {
alert( arr[i] );
}
for (let fruit of fruits) {
alert( fruit );
}
배열을 다루는 메서드들을 알아보자. 배열은 많이 쓰이는 자료구조인 만큼 그 메서드의 쓰임 또한 잘 알아두는 것이 매우 중요. 예를 들어 자바스크립트를 학습한 뒤, 리액트를 공부한다고 해도, 자료의 불변성과 리덕스 상태관리에 꼭 알아두어야 하는 부분임으로 잘 알아두도록(?) 저한테 하는 말입니닿ㅎㅎ
🔑 아래에 살펴볼 배열 메서드들에 예시가 되는 메서드를 정의
let fruits = ["사과", "딸기", "귤", "바나나", "수박"];
push
, 마지막 값을 빼내는 pop
fruits.push("포도") // ["사과", "딸기", "귤", "바나나", "수박", "포도"]
fruits.pop() // ["사과", "딸기", "귤", "바나나", "수박"]
unshift
, 가장 처음 인덱스 값을 빼내는 shift
fruits.unshift("포도") // ["포도", "사과", "딸기", "귤", "바나나", "수박"]
fruits.pop() // ["사과", "딸기", "귤", "바나나", "수박"]
📏 arr.splice(index[, deleteCount, elem1, ..., elemN])
fruits.splice(1, 1) // ["사과", "귤", "바나나", "수박"]
// 1번째 인덱스에서 1개 삭제
fruits.splice(1, 0, "딸기", "머루")
// ["사과", "딸기", "머루", 귤", "바나나", "수박"]
//1번째 인덱스에서 0개를 지우고 "딸기"와 "머루" 삽입
📏 arr.slice([start], [end])
fruits.slice(2, 3) // ["머루"] 반환
📏 arr.concat(arg1, arg2...)
fruits.concat(["산딸기", "복숭아"], ["배"])
// ["사과", "딸기", "머루", 귤", "바나나", "수박", "산딸기", "복숭아", "배"]
파라미터로 들어온 배열의 값을 기존의 배열에 순서대로 합쳐줌
fruits.forEach((item, index, array) => {
alert(`${item} is at index ${index} in ${array});
});
item
에 배열의 각각 요소가 index
는 해당 요소의 인덱스가 array
는 forEach를 호출한 배열 자체가 들어감
📏 arr.indexOf(item, from)
📏 arr.lastIndexOf(item, from)
fruits.indexOf("사과") // 0
fruits.lastIndexOf("머루", 3) // 2
📏 arr.includes(item, from)
fruits.includes("사과") // true
fruits.includes("머루", 3) // false, 값이 있지만 2번째 인덱스에 있으므로 3번째 인덱스부터 서칭했기 때문에 false 반환
콜백함수
가 true를 반환하면 그 요소를 반환함let result = arr.find(function(item, index, array) {
// true가 반환되면 반복이 멈추고 해당 요소를 반환합니다.
// 조건에 해당하는 요소가 없으면 undefined를 반환합니다.
});
-파라미터 정의-
item – 함수를 호출할 요소
index – 요소의 인덱스
array – 배열 자기 자신
filter
함수는 일치하는 모든 요소를 반환해줌.let results = arr.filter(function(item, index, array) {
// 조건을 충족하는 요소는 results에 순차적으로 더해집니다.
// 조건을 충족하는 요소가 하나도 없으면 빈 배열이 반환됩니다.
});
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
// 앞쪽 사용자 두 명을 반환합니다.
let someUsers = users.filter(item => item.id < 3);
alert(someUsers.length); // 2
let result = arr.map(function(item, index, array) {
// 요소 대신 새로운 값을 반환.
});
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6
🎢 여기 아래 부터 나오는 메서드는 대상이 되는 배열 자체에 변형을 줌
배열 자체
가 변경됨. 배열의 정렬 기준을 따로 정의해 주기 위해선 콜백함수(fn)
를 파라미터로 전달해주어야 함.function compareNumeric(a, b) {
if (a > b) return 1;
if (a == b) return 0;
if (a < b) return -1;
}
let arr = [ 1, 2, 15 ];
arr.sort(compareNumeric);
alert(arr); // 1, 2, 15
이처럼 정렬 기준을 정의해주는 함수(ordering function)을 전달해 주지 않으면 사전편집 순으로 정렬된다는 것을 기억하자.
let arr = [1, 2, 3, 4, 5];
arr.reverse();
alert( arr ); // 5,4,3,2,1
let names = 'Bilbo, Gandalf, Nazgul';
let arr = names.split(', ');
for (let name of arr) {
alert( `${name}에게 보내는 메시지` ); // Bilbo에게 보내는 메시지
}
let arr = ['Bilbo', 'Gandalf', 'Nazgul'];
let str = arr.join(';'); // 배열 요소 모두를 ;를 사용해 하나의 문자열로 합침.
alert( str ); // Bilbo;Gandalf;Nazgul
typeof
연산자를 통해 객체와 배열을 구분할 수 없음 typeof {} // object;
typeof [] // object;
alert(Array.isArray({})); // false
alert(Array.isArray([])); // true
Array.isArray를 통해 배열 여부를 확인 후 boolean값 반환
자바스크립트에서 정말 중요한 부분이라고 할 수 있는 객체와 배열에 대해서 정리해 보았다. 위에 나열되어있는 정보들로 두 가지 자료구조를 모두 알아보았다곤 할 수 없지만, 정리하며, 기본적인 내용을 충분히 숙지할 수 있었다. 앞으로 새롭게 알게 되는 내용이나 부족한 부분들은 다시 추가적으로 정리하거나, 또 다른 블로그 글로 정리할 예정!😜