[JavaScript] 객체

Jin·2021년 10월 24일
0

JavaScript

목록 보기
8/12
post-thumbnail

1. 리터럴과 프로퍼티

자바스크립트에는 8개 자료형이 있는데 이 중 7개는 오직 하나의 데이터(문자열, 숫자)만 담을 수 있어 원시형(Primitive type)이라고 부른다.

하지만 객체형은 원시형과 달리 다양한 데이터를 담을 수 있다. 키로 구분된 데이터집합이나 복잡한 개체를 {}를 이용하여 저장 할 수 있다.
중괄호 안에는 '키(key):값(value)' 쌍으로 구성된 프로퍼티를 여러개 넣을 수 있는데, key에는 문자형, value에는 모든 자료형이 허용된다.

let user = new Object(); // 객체 생성자 문법
let user = {}; // 객체 리터럴 문법(주로 이 방법 사용)

let user = {
  name : 'John',
  age : 30
};

alert( user.name ); // John
alert( user.age ); // 30

프로퍼티 값을 추가 혹은 삭제 또한 할 수 있다.

user.isAdmin = true;

delete user.age;

여러 단어를 조합해 프로퍼티 이름을 만든 경우는 프로퍼티 이름을 따옴표로 묶어줘야 한다.

let user = {
  name : 'John',
  age : 30,
  "like birds":true
};

상수 객체는 수정 될 수 있다.
const로 선언된 객체 는 수정 될 수있다. 헷갈리지 말자!

const user = {
  name : "John",
};

user.name = "Pete"; 
alert(user.name); // Pete

constuser의 값을 고정하지만, 그 내용은 고정하지 않는다.

2. 대괄호 표기법

여러 단어를 조합해 프로퍼티 키를 만든 경우에는, 점 표기법을 사용해 프로퍼티 값을 읽을 수 없다.

user.likes birds = true // Error

이러한 경우에는 점 표기법 대신 '대괄효 표기법' 방법을 사용 할 수 있다.

let user = {};

//set
user["likes birds"] = true;

//get
alert(user["likes birds"]); // true

//delete
delete user["like birds"]);

변수를 키로 사용할 수 도 있다.

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

let key= prompt("Which information do you want?", "name");

alert(user[key] ); // John(프롬프트 창에 "name"을 입력한 경우)

하지만 점 표기법은 이런 방식이 불가능하다.

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

let key = "name";
alert( user.key ) //undefined

1) 계산된 프로퍼티

객체를 만들 때 객체 리터럴 안의 프로퍼티 키가 대괄호로 둘러싸여 있는경우, 이를 계산된 프로퍼티라고 부른다.

let fruit = prompt("which fruit do you want?", "apple");

let bag = {
  [fruit]: 5,	// 변수 fruit에서 프로퍼티의 이름을 동적으로 받아온다.
};

alert( bag.apple); // fruit에 "apple"이 할당되었다면, 5가 출력 된다.

3. 단축 프로퍼티

function makeUser(name, age){
  return {
    name: name,
    age: age,
  };
}

let user = makeUser("John", 30);
alert(user.name); // John

위 코드와 같이 이름과 값의 변수 이름이 동일 할 때는 name:name이 아닌 name만 적어도 프로퍼티를 설정 할 수 있다.

function makeUser(name, age){
  return {
    name,
    age,
  };
}

//일반 프로퍼티와 단축 프로퍼티 함께 사용도 가능
function makeUser(name, age){
  return {
    name,
    age: 30
  };
}

4. 프로퍼티 이름 제약사항

변수 이름으로는 'for', 'let', 'return' 같은 예약어를 사용하면 안되지만 객체 프로퍼티엔 이런 제약이 없다.

let obj = {
  for : 1,
  let : 2,
  return : 3
};

alert( obj.for + obj.let + obj.return); // 6

문자형이나 심볼형에 속하지 않은 값은 문자열로 자동 형 변환이 된다.
예를 들어, 키에 숫자 0을 넣으면 문자열 "0"으로 자동변환 된다.

let obj = {
  0:"test"
};

alert( obj["0"] ); // test
alert( obj[0] ); // test

이와 객체 프로퍼티 키에 쓸 수 있는 문자열에 제약이 없지만, 예외가 하나있다. 바로 __proto__이다. 역사적인 이유때문이라고 한다.

5. 'in' 연산자로 프로퍼티 존재 여부 확인하기

자바스크립트 객체 특징 중 하나는 존재하지 않는 프로퍼티에 접근하려 해도 에러가 발생하지 않고 undefined를 반환한다는 것이다.

let user = {};
alert(user.noSuchProperty === undefined); // true

// in을 사용하여 프로퍼티 존재 여부도 확인이 가능하다

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

alert( "age" in user ); // user.age 존재하므로 true
alert( "abc" in user ): // false

in 왼쪽에는 반드시 프로퍼티 이름이 와야한다. 프로퍼티 이름은 보통 따옴표로 감싼 문자열이다.
따옴표를 생략하면 아래 예시와 같이 엉뚱한 변수가 조사 대상이 된다.

let user = {
  age : 30
};

let key = "age";
alert( key in user ); // true, 변수 key에 저장된 값("age")를 사용해 프로퍼티 존재 여부를 확인 할 수 있다.

대부분 경우, 일치 사용자를 사용해 프로퍼티 존재 열부를 알아낼 수 있지만, 가끔 실패 하는경우가 있다. 이럴 때 in을 사용 할 수 있다.

let obj = {
  test : undefined
};

alert( obj.test ); // 값이 'undefined'이므로, 얼럿 창에 undefined가 출력 된다.
alert( "test" in obj); // true가 출력

for .. in 반복문

for..in 반복문을 사용하면 객체의 모든 키를 순회 할 수 있다.

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

for (let key in user) {
  //키
  alert(key);; // name, age, isAdmin
  alert( user[key] ); // John, 30, true

객체 정렬 방식

정수 프로퍼티는 자동으로 정렬되고, 그 외의 프로퍼티는 객체에 추가한 순서 그대로 정렬이 된다.

let codes = {
  "49": "독일",
  "41": "스위스",
  "44": "영국",
  "1": "미국"
};

for (let code in codes) {
  alert(code); // 1, 41, 44, 49
}

만약 입력 순서대로 출력되길 원하면 정수로 취급되지 않도록 하면된다. 위의 같은 케이스에서는 정수 앞에 +를 붙이면 된다.

6. 참조에 의한 객체 복사

원시값은 '값 그대로' 저장, 할당되고 복사되지만 객체는 '참조에 의해' 저장되고 복사 된다.

let user = { name:"John" };
let admin = user;
admin.name = 'Pete'
alert(user.name) // Pete 출력됨

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

1) 참조에 의한 비교

객체 비교 시 동등 연산자 ==와 일치 연산자 ===는 동일하게 동작한다.
비교 시 피연산자인 두 객체가 동일한 객체인 경우에 참을 반환

let a = {};
let b = a;

alert( a == b ); // true
alert( a === b ); // true

7. 객체 복사, 병합과 Obejct.assgin

기존에 있던 객체와 똑같으면서 독립적인 객체를 만들려면 어떻게 해야할까?
자바스크립트는 객체 복제 내장 메서드를 지원하지 않기 때문에 조금 어렵다.
정말 복제가 필요하면 새로운 객체를 만든 다음 기존 객체의 프로퍼티들을 순회해 원시 수준까지 프로퍼티를 복사 해야한다.

  • 원시 수준까지 복사
let user = {
  name:"Jin",
  age:29
};

let cloe = {};

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

clone.name = "Pete"

alert(user.name); // 기존 객체에는 여전히 Jin이 있다.
  • Obejct.assign 사용
Object.assign(dest, [src1, src2, src3...])
  • 첫 번째 인수 dest는 목표로 하는 객체
  • 이어지는 인수 src1, ...., srcN은 복사하고자 하는 객체.
  • 객체 src1, .. , srcN의 프로퍼티를 dest에 복사.
  • 마지막으로 dest를 반환.
let user = { name: "John" };

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

// permissions1과 permissions2의 프로퍼티를 user로 복사합니다.
Object.assign(user, permissions1, permissions2);

// now user = { name: "John", canView: true, canEdit: true }

목표 객체(user)에 동일한 이름을 가진 프로퍼티가 있는 경우에는 기존 값이 덮어 씌워 진다.

let user = { name: "John" };

Object.assign(user, { name: "Pete" });

alert(user.name); // user = { name: "Pete" }

출처 : https://ko.javascript.info

profile
내가 다시 볼려고 작성하는 블로그. 아직 열심히 공부중입니다 잘못된 내용이 있으면 댓글로 지적 부탁드립니다.

0개의 댓글