Posts 모던 자바스크립트 #4.1. 객체
Post
Cancel

모던 자바스크립트 #4.1. 객체

모던 JavaScript 튜토리얼을 따라가면서 정리합니다.

4.1. 객체

  • 여덟 개의 자료형 중 일곱 개는 오직 하나의 데이터만 담을 수 있어 원시형(primitive type)이라 부른다.

  • 반면 객체형키로 구분된 데이터 집합이나 복잡한 개체(entity)와 같이 다양한 데이터를 저장할 수 있다.

  • 객체는 몇가지 특수한 기능을 가진 연관 배열(associative array)

  • 프로퍼티는 키(key) : 값(value) 쌍으로 이루어져 잇다.

    • key엔 문자열이거나 심볼이 허용된다. 보통 문자열이다.
    • value엔 모든 자료형이 허용된다.
  • 프로퍼티 키는 프로퍼티 이름 **또는 **식별자라고도 부른다.

  • 객체에선 키를 이용해 프로퍼티를 쉽게 찾을 수 있다.

    점 표기법(dot notation)을 이용해 프로퍼티 값을 읽는다.

  • 프로퍼티 삭제: delete user.age;

  • 프로퍼티 이름이 복수의 단어일 경우 따옴표로 묶어 줘야 한다.

  • trailing, hanging 쉼표: 마지막 프로퍼티 끝은 쉼표로 끝날 수 있다. => 프로퍼티 추가, 삭제, 이동 용이

  • 상수(const로 선언된) 객체는 수정될 수 있다. const는 객체의 값을 고정하지만, 그 내용은 고정하지 않는다.

  • 빈 객체를 만드는 방법

    • 객체 생성자 문법: let user = new Object()
    • 객체 리터럴(object literal)문법: let user = {}

대괄호 표기법

  • 유효한 변수 식별자
    • 공백이 없다.
    • 숫자로 시작하지 않는다.
    • $, _를 제외한 특수 문자가 없어야 한다.
  • 키가 유효한 변수 식별자가 아닌 경우 대괄호 표기법(square bracket notation)을 사용해야 한다.

    대괄호 표기법 안에서 문자열을 사용할 땐 문자열을 따옴표로 묶어줘야 한다.

    대괄호 표기법을 사용할 경우 문자열 뿐만 아니라 모든 표현식의 평가 결과를 프로퍼티로 사용할 수 있다. 다음 코드에서는 변수를 키로 사용하였다.

    1
    2
    3
    
    let key = "like birds";
      
    user[key] = true;
    

    변수 key는 런타임에 평가되기 때문에 사용자 입력값 변경 등에 따라 값이 변경될 수 있다. 어떤 경우든, 평가가 끝난 이후의 결과가 프로퍼티 키로 사용된다. 이를 응용하면 코드를 유연하게 작성할 수 있다. 점 표기법은 이런 방식이 불가능하다.

계산된 프로퍼티(computed property)

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

    1
    2
    3
    4
    5
    6
    7
    
    let fruit = prompt("어떤 과일을 구매하시겠습니까?", "apple");
      
    let bag = {
      [fruit] = 5, // 변수 fruit에서 프로퍼티 이름을 동적으로 받아온다.
    };
      
    alert(bag.apple); // fruit에 apple이 할당되었다면, 5가 출력된다.
    

    아래 예시는 위 예시와 동일하게 동작한다.

    1
    2
    3
    4
    5
    6
    
    let fruit = prompt("어떤 과일을 구매하시겠습니까?", "apple");
      
    let bag = {};
      
    // 변수 fruit을 사용해 프로퍼티 이름을 만든다.
    bag.fruit = 5;
    

    대괄호 안에는 복잡한 표현식이 올 수 있다.

    1
    2
    3
    4
    
    let fruit = 'apple';
    let bag = {
      [fruit + 'Computers']: 5 // bag.appleComputers = 5
    };
    
  • 대괄호 표기법은 프로퍼티 이름과 값의 제약을 없애주기 때문에 점 표기법보다 강력하다. 그러나 작성하기 번거롭다.

  • 프로퍼티 이름이 확정된 상황이고, 단순한 이름이라면 점 표기법을 사용하다가 복잡한 상황이 발생했을 때 대괄호 표기법으로 바꾸는 경우가 많다.

단축 프로퍼티

  • 실무에서는 프로퍼티 값을 기존 변수에서 받아와 사용하는 경우가 종종 있다. 이 경우 프로퍼티 값 단축 구문(property value shorthand)를 사용하면 변수를 사용해 프로퍼티를 쉽게 만들 수 있다.

  • 사용 전

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    function makeUser(name, age) {
      return {
        name: name,
        age: age,
        // ...등등
      };
    }
      
    let user = makeUser("John", 30);
    alert(user.name); // John
    

    사용 후

    1
    2
    3
    4
    5
    6
    7
    
    function makeUser(name, age) {
      return {
        name, // name: name 과 같음
        age,  // age: age 와 같음
        // ...
      };
    }
    

프로퍼티 이름의 제약사항

  • 예약어를 객체 프로퍼티 키로 사용해도 된다.

    1
    2
    3
    4
    5
    6
    7
    
    let obj = {
      for: 1,
      let: 2,
      return: 3
    };
      
    alert( obj.for + obj.let + obj.return );  // 6
    

    프로퍼티 이름엔 특별한 제약이 없다. 어떤 문자형, 심볼형 값도 프로퍼티 키가 될 수 있다.

  • 문자형이나 심볼형에 속하지 않은 값은 문자열로 자동 형 변환된다.

  • __proto__의 경우 역사적인 이유 때문에 특별 대우를 받는다.

    1
    2
    3
    
    let obj = {};
    obj.__proto__ = 5; // 숫자를 할당한다.
    alert(obj.__proto__); // [object Object] - 숫자를 할당했지만 값은 객체가 되었다. 의도한대로 동작하지 않는다.
    

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

  • 존재하지 않는 프로퍼티에 접근하려 해도 에러가 발생하지 않고 undefined를 반환한다. (null을 반환하는 자바와 다르다.) 따라서 일치연산자를 사용해 undefined과 프로퍼티 이름을 비교하여 프로퍼티 존재 여부를 확인할 수 있다.

    그러나 프로퍼티는 존재하는데 값에 undefined를 할당한 경우 프로퍼티 존재 여부를 제대로 판단할 수 없다. 이 경우 프로퍼티는 존재하지만 판단 결과는 false가 되기 때문이다.

  • 이 외에도 연산자 in을 사용하면 프로퍼티 존재 여부를 확인할 수 있다.

  • "key" in object

  • 1
    2
    3
    4
    5
    6
    7
    
    let obj = {
      test: undefined
    };
      
    alert( obj.test ); // 값이 `undefined`이므로, 얼럿 창엔 undefined가 출력된다. 그런데 프로퍼티 test는 존재한다.
      
    alert( "test" in obj ); // `in`을 사용하면 프로퍼티 유무를 제대로 확인할 수 있다(true가 출력됨).
    

for...in 반복문

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

  • 문법

    1
    2
    3
    
    for (key in object) {
      // 각 프로퍼티 키(key)를 이용하여 본문(body)을 실행한다.
    }
    
  • 반복 변수 명은 자유롭게 정할 수 있다.

객체 정렬 방식

  • 객체는 특별한 방식으로 정렬된다. 정수 프로퍼티(integer property)는 자동으로 정렬되고, 그 외의 프로퍼티는 객체에 추가한 순서 그대로 정렬된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    let codes = {
      "49": "독일",
      "41": "스위스",
      "44": "영국",
      // ..,
      "1": "미국"
    };
      
    for (let code in codes) {
      alert(code); // 1, 41, 44, 49
    }
    
  • 정수 프로퍼티: 변형 없이 정수에서 왔다 갔다 할 수 있는 문자열

  • 위 예시에서 객체에 추가한 순서대로 정렬하기 위해서는 각 나라 번호가 정수로 취급되지 않도록 각 나라 번호 앞에 "+"를 붙이면 된다.

자바스크립트에는 일반 객체 외에도 다양한 종류의 객체가 있다.

  • Array: 정렬된 데이터 컬렉션을 저장할 때 쓰인다.
  • Date: 날짜와 시간 정보를 저장할 때 쓰인다.
  • Error: 에러 정보를 저장할 때 쓰인다.

Array와 Date은 객체형에 속한다. 객체에 다양한 기능을 넣어 확장한 또 다른 객체이다.

과제

객체야 안녕?

1
2
3
4
5
let user = {};
user.name = "John";
user.surname = "Smith";
user.name = "Pete";
delete user.name;

객체가 비어있는지 확인하기

1
2
3
4
5
6
7
let schedule = {};

alert( isEmpty(schedule) ); // true

schedule["8:30"] = "get up";

alert( isEmpty(schedule) ); // false
1
2
3
4
5
6
function isEmpty(obj) {
  for (let key in obj) {
    return false;
  }
  return true;
}

프로퍼티 합계 구하기

1
2
3
4
5
6
7
8
9
10
11
12
13
let salaries = {
  John: 100,
  Ann: 160,
  Pete: 130
}

let sum = 0;

for (let key in salaries) {
  sum += salaries[key]; 
}

alert(sum);

프로퍼티 값 두 배로 부풀리기

1
2
3
4
5
6
7
function multiplyNumeric(obj) {
  for (let key in obj) {
    if (typeof obj[key] === "number") {
      obj[key] *= 2;
    }
  }
}
This post is licensed under CC BY 4.0 by the author.

스프링 입문 #7 AOP(Aspect Oriented Programming)

모던 자바스크립트 #4.2. 참조에 의한 객체 복사

Loading comments from Disqus ...