javascript - 배열, 객체

김예찬·2021년 5월 1일
0

자바스크립트에서 가장 중요한 데이터 구조, 객체와 배열에 대해 정리😋

시작하기

자바스크립트에서 대부분의 자료구조는 배열과 객체이다. 서버와 통신을 통해 받아오는 데이터도 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, index

배열은 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
    배열의 마지막에 새로운 값을 추가하는 push, 마지막 값을 빼내는 pop
fruits.push("포도") // ["사과", "딸기", "귤", "바나나", "수박", "포도"]
fruits.pop() // ["사과", "딸기", "귤", "바나나", "수박"]
  • shift, unshift
    배열의 가장 앞에 새로운 값을 추가 unshift, 가장 처음 인덱스 값을 빼내는 shift
fruits.unshift("포도") // ["포도", "사과", "딸기", "귤", "바나나", "수박"]
fruits.pop() // ["사과", "딸기", "귤", "바나나", "수박"]
  • splice
    배열의 요소를 추가 삭제 교체 모든 걸 할 수 있는 메서드
	📏 arr.splice(index[, deleteCount, elem1, ..., elemN])

	fruits.splice(1, 1) // ["사과", "귤", "바나나", "수박"]
	// 1번째 인덱스에서 1개 삭제

	fruits.splice(1, 0, "딸기", "머루")
	// ["사과", "딸기", "머루", 귤", "바나나", "수박"]
	//1번째 인덱스에서 0개를 지우고 "딸기"와 "머루" 삽입
	
  • slice
    첫번째 파라미터부터 두번째 파라미터 전까지 반환
	📏 arr.slice([start], [end])

	fruits.slice(2, 3) // ["머루"] 반환
  • concat
    기존 배열의 요소를 사용해 새로운 배열을 만들거나 기존 배열에 요소를 추가하고자 할때 사용
	📏 arr.concat(arg1, arg2...)

	fruits.concat(["산딸기", "복숭아"], ["배"]) 
	// ["사과", "딸기", "머루", 귤", "바나나", "수박", "산딸기", "복숭아", "배"]

파라미터로 들어온 배열의 값을 기존의 배열에 순서대로 합쳐줌

  • forEach
    배열의 요소에 주어진 함수를 실행시킴
fruits.forEach((item, index, array) => {
	alert(`${item} is at index ${index} in ${array});
});

item에 배열의 각각 요소가 index는 해당 요소의 인덱스가 array는 forEach를 호출한 배열 자체가 들어감

  • indexOf, lastIndexOf
    파라미터의 인덱스 값을 알려주는데 last는 검색을 끝에서 시작한다는 점만 다름
  📏 arr.indexOf(item, from)
  📏 arr.lastIndexOf(item, from)

fruits.indexOf("사과") // 0
fruits.lastIndexOf("머루", 3) // 2
  • includes
    파라미터로 들어온 값이 배열에 들어 있는지 확인 후 boolean값 반환
  📏 arr.includes(item, from)
fruits.includes("사과") // true
fruits.includes("머루", 3) // false, 값이 있지만 2번째 인덱스에 있으므로 3번째 인덱스부터 서칭했기 때문에 false 반환
  • find, findIndex
    주어진 콜백함수가 true를 반환하면 그 요소를 반환함
let result = arr.find(function(item, index, array) {
  // true가 반환되면 반복이 멈추고 해당 요소를 반환합니다.
  // 조건에 해당하는 요소가 없으면 undefined를 반환합니다.
});
  -파라미터 정의-
  item – 함수를 호출할 요소
  index – 요소의 인덱스
  array – 배열 자기 자신
  • filter
    find가 주어진 콜백함수를 만족하는 하나의 요소를 반환하는 반면 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
  • map
    요소 전체를 대상으로 함수를 호출하고, 함수 호출 결과를 배열로 반환해줌
let result = arr.map(function(item, index, array) {
  // 요소 대신 새로운 값을 반환.
});

let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6

🎢 여기 아래 부터 나오는 메서드는 대상이 되는 배열 자체에 변형을 줌

  • sort(fn)
    배열의 요소를 정렬해줌. 배열 자체가 변경됨. 배열의 정렬 기준을 따로 정의해 주기 위해선 콜백함수(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)을 전달해 주지 않으면 사전편집 순으로 정렬된다는 것을 기억하자.

  • reverse
    요소를 역순으로 정렬시켜주는 메서드
let arr = [1, 2, 3, 4, 5];
arr.reverse();

alert( arr ); // 5,4,3,2,1
  • split
    배열의 메서드는 아니지만, 문자열을 split의 파라미터를 기준으로 쪼개서 배열에 담아 반환
let names = 'Bilbo, Gandalf, Nazgul';

let arr = names.split(', ');

for (let name of arr) {
  alert( `${name}에게 보내는 메시지` ); // Bilbo에게 보내는 메시지
}
  • join(glue)
    split에 반대되는 메서드. 배열의 모든 요소를 파라미터를 사용해 하나의 문자열로 반환
let arr = ['Bilbo', 'Gandalf', 'Nazgul'];

let str = arr.join(';'); // 배열 요소 모두를 ;를 사용해 하나의 문자열로 합침.

alert( str ); // Bilbo;Gandalf;Nazgul
  • Array.isArray
    자바스크립트에서 배열은 독립된 자료형이 아닌 객체형에 속함. 그래서 typeof 연산자를 통해 객체와 배열을 구분할 수 없음
	typeof {} // object;
	typeof [] // object;

        alert(Array.isArray({})); // false
        alert(Array.isArray([])); // true

Array.isArray를 통해 배열 여부를 확인 후 boolean값 반환

끝맺기

자바스크립트에서 정말 중요한 부분이라고 할 수 있는 객체와 배열에 대해서 정리해 보았다. 위에 나열되어있는 정보들로 두 가지 자료구조를 모두 알아보았다곤 할 수 없지만, 정리하며, 기본적인 내용을 충분히 숙지할 수 있었다. 앞으로 새롭게 알게 되는 내용이나 부족한 부분들은 다시 추가적으로 정리하거나, 또 다른 블로그 글로 정리할 예정!😜

profile
프론트엔드

0개의 댓글