# [JS] 4-1. 객체

heyhey·2023년 2월 22일
0

JavaScript

목록 보기
7/14

JS의 자료형 종류는 8가지가 있다. 7개는 문자, 숫자 등만 담을 수 있는 '원시형'이라고 불리는 것들이다.
객체는 그와 달리 다양한 데이터를 담을 수 있다. 키로 구분된 데이터 집합 / 복잡한 개체(entity)를 저장할 수 있다.

객체


생성

  • new Object()
  • {} : 중괄호를 이용해 객체를 선언하는 것을 객체 리터럴 이라고 부른다.

const 로 선언된 객체는 수정이 가능하다.
상수를 의도하고 만들었지만 수정이 가능하기 때문에 주의해야한다.

제거

user ={name:"hong",age:18}
delete user.age => {name:"hong"}
delete user.name =>  {}
delete user => error

delete 를 이용해 프로퍼티 삭제 및 전체 객체도 삭제가능하다.

대괄호 표기 vs 점 표기(.)

user = {
  name: "hi",
  "my name": "hong",
};

user.name 과 같은 코드는 JS가 쉽게 할 수 있다.
하지만 키가 한 문자열이 아니라면?
user.my name...? 이럴 때 사용하는 것이 대괄호 표기법이다.

키가 유효한 변수 식별자가 아닌 경우에 사용하면 된다.
user["my name"]

변수는 런타임에 평가되기 때문에 변경될 수 있다. 대과롷 표기를 이용하면 평가가 끝난 이후의 결과가 프로퍼티 키로 사용되기 때문에 유연하게 코드 작성이 가능하다.

user = {
  name:"hong"
}

let key = "name"
user[key] => "hong"

대괄호 표기는 프로퍼티 이름과 제약을 없애주기 때문에 점 표기보다 훨씬 강력하다.
하지만 작성하기 번거롭기 때문에 처음엔 점 표기를 사용하다가 복잡한 상황이 발생했을 때 대괄호로 많이 사용한다.

단축 프로퍼티


fucntion makeUser(name,age){
  return {
    name,
    user
  }
}

위와 같은 함수는 {name:name,age:age} 의 코드를 줄인 것이다.

in


프로퍼티의 존재 여부를 확인할 수 있다.

let user = {name:"hong",age:30}
"age" in user => true
"ag2e" in user => false

for ... in


for ... in 은 앞서 배운 for(a;b;c) 과는 완전히 다르다.

for in 을 사용하면 객체의 모든 프로퍼티가 출력된다.

let user = {
  name: "John",
  age: 30,
  isAdmin: true
};

for (let key in user) {
  console.log(key) => name,age,isAdmin
  console.log(user[key]) => John,30,true
}

객체 정렬 방식


객체는 프로퍼티가 정수일 때는 순서대로 정렬된다.
하지만 문자열은 정렬되지 않는다.

참조


참조에 의한 객체 복사

객체와 원시 타입의 차이는 참조에 의해 저장되고 복사된다는 점이다.
원시값은 값 그대로 저장할당된다.

이게 무슨말이냐

원시

a = 1 , a = b 를 실행하게 되면 독립된 두개의 변수에 각각 1이 할당된다.
b를 바꿔도 a에는 영향을 끼치지 않는다.

객체

변수엔 객체가 저장되는 것이 아니라, 객체가 저장되어 있는 '메모리주소'인 객체에 대한 '참조값'이 저장된다.

아하~
a = {val:1} 를 저장하면 a의 메모리 참조값이 생긴다 => a35832kdf8
b = a 를 실행하면 저 메모리 참조값을 복사해 가져오기 때문에 객체자체는 복사되지 않는다.

변수는 두개이지만 각 변수엔 동일 객체에 대한 참조값이 저장된다.

참조에 의한 비교

위에서의 a,b 를 비교하면 a===b a==b 둘다 true 의 결과가 나온다.
두 변수가 같은 객체를 참조하기 때문이다.

하지만 a = {}, b={} 일때는 false가 출력된다. 각각이 독립된 개체이기 때문에 일치하지 않는다는 뜻이다.

(나는 JSON.stringfy를 이용해 비교한다)

객체 복제

객체를 복제하는 방법은 어떻게 할까? JS는 복제 내장 메서드가 없기 때문에 어렵다 (사실 객체를 복제할 일은 거의 없다.)

그래도 한다면 방법은 다음과 같다.

let clone = {}; // 새로운 빈 객체

// 빈 객체에 user 프로퍼티 전부를 복사해 넣습니다.
for (let key in user) {
  clone[key] = user[key];
}

Object.assign

Object의 첫번째 인수에 두번째 인수부터의 프로퍼티를 복사한다.

let user = { name: "John" };

let permissions1 = { canView: true };
let permissions2 = { canEdit: true };

Object.assign(user, permissions1, permissions2);
user => { name: "John", canView: true, canEdit: true }

복사는 다음과 같이 하면된다.
let clone = Object.assign({}, user);

깊은 복사

하지만 이건 깊이가 1일때만 가능하다.

user = {
  name:"hi",
  size:{
    height:150,
    width:4
  }
}

user2 = Object({},user)
user2.name = 'bye'
user2.size.height = 100

위와 같이 설정을 해줬다면
user.name 은 원하는 대로 'hi'가 나온다.
하지만 user.size.height 은 150 이 아닌 100이 나온다.

객체안의 객체또한 메모리상 주소가 참조되어서 그런건데, 이걸 해결하기 위해서는 객체 구조도 복사할 수 있는
반복문을 이용해야한다.
하지만 귀찮다.. lodash 의 _cloneDeep()을 이용해서 깊은 복사를 사용할 수 있다.

profile
주경야독

0개의 댓글