파트 1 - 3) 객체: 기본 - 1) 객체

Lee·2021년 10월 12일
0

객체: 기본 챕터의 객체 파트 링크 : https://ko.javascript.info/object

객체

자바스크립트의 자료형 중 하나의 데이터(문자열, 숫자 등)만 담을 수 있는 것을 '원시형(primitive type)'이라고 부른다. 객체를 제외한 자료형들이 원시형이다.

객체를 만드는 방법에는 생성자 문법리터럴 문법 두가지가 있다.

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

리터럴과 프로퍼티

1) delete 연산자를 사용하면 프로퍼티(객체의 속성)를 삭제할 수 있다.

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

3) 프로퍼티의 끝은 쉼표로 끝날 수 있다. 이런 마지막에 찍히는 쉼표를 'trailing(길게 늘어지는)' 혹은 'hanging(매달리는)' 쉼표라고 부른다.

주의! - 상수로 선언된 객체는 수정될 수 있다!


위와 같이 상수로 선언된 객체 내의 프로퍼티를 수정하는 것은 문제가 안되고 아래처럼 객체를 통째로 수정하려 할 경우에 오류가 발생한다.

(상수 객체의 프로퍼티를 만드는 다른 방법은 '프로퍼티 플래그와 설명자' 챕터(https://ko.javascript.info/property-descriptors)에서 다룬다고 한다.)


대괄호 표기법

여러 단어를 조합해 프로퍼티 키를 만든 경우엔, 점 표기법(객체.프로퍼티 키)을 사용해 프로퍼티 값을 읽을 수 없다.
(위에서 작성한 예시중 'where live' 키가 여기에 해당한다.)

키가 유효하려면 공백이 없어야 하고, 숫자로 시작하면 안되고, 특수기호는 $와 _만 들어갈 수 있다.
만약 위 조건들을 충족하지 못하는 유효하지 않은 키를 읽어야한다면 점 표기법 대신 '대괄호 표기법'을 사용할 수 있다.

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

변수는 런타임에(=실행될 동안) 평가되어 사용자가 입력한 값 변경 등에 따라 값이 변경될 수 있다.
평가가 끝난 이후의 결과가 프로퍼티 키로 쓰인다.

<script>
  let user = {
    name: "lee",
    age: 45
  };

  let key = prompt("사용자의 어떤 정보를 얻고 싶으신가요?", "name");

  // 변수로 접근
  alert( user[key] ); // 프롬프트 창에 "name"을 입력한 경우 lee가 출력된다.
</script>

대괄호 문법을 쓰면 위와 같이 사용자가 입력한 값을 변수에 저장시키고 그 변수를 객체의 key 값으로 사용할 수 있다!

점 표기법은 위와 같은 사용이 불가능하다.

<script>
  let user = {
    name: "lee",
    age: 45
  };

  let key = "name";
  alert( user.key ); // user.name으로 인식되지 않고 undefined가 반환된다.
</script>

계산된 프로퍼티

객체 리터럴 안의 프로퍼티 키가 대괄호로 감싸진 것을 '계산된 프로퍼티(computed property)'라고 한다.
계산된 프로퍼티는 프로퍼티에 들어갈 값을 동적으로 받아온다.

<script>
  let fruit = prompt("어떤 과일을 구매하시겠습니까?", "apple");

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

  alert( bag.apple ); // fruit에 "apple"이 입력됐으면, apple이라는 키의 값인 5를 출력한다.
  // ----------------------------------------------------------------------------
  // 또는 아래처럼 좀 더 간략하게 작성할 수도 있다.
  
  let fruit = prompt("어떤 과일을 구매하시겠습니까?", "apple");
  let bag = {};
  
  bag[fruit] = 5;
  // bag.apple을 출력하면 5가 출력된다.
  
  //-----------------------------------------------------------------------------
  // 또는 아래처럼 연산을 넣어 사용할 수도 있다. 
  
  let fruit = 'apple';
  
  let bag = {
    [fruit + 'Computers']: 5 // bag.appleComputers = 5
  };
</script>

단축 프로퍼티

프로퍼티 이름(key)과 값이 매개변수로 받는 변수명과 동일하다면 프로퍼티 값 단축 구문을 사용하여 코드를 간략하게 작성할 수 있다.

<script>
  function makeUser(name, age) {
    return {
      name: name,
      age: age,
      ...
    };
  }

  let user = makeUser("lee", 45);
  alert(user.name); // lee
  //===========================================================
  // 위 코드를 단축 프로퍼티 문법으로 바꿔봤다!
  
  function makeUser(name, age) {
    return {
      name, // name: name 과 같음
      age,  // age: age 와 같음
      ...
    };
}
</script>

한 객체 안에서 일반 프로퍼티 문법과 단축 프로퍼티 문법을 혼용할 수도 있다.

<script>
  let user = {
    name,  // name: name 과 같음
    age: 45
  };
</script>

프로퍼티 이름의 제약사항

변수명과는 다르게 프로퍼티의 이름에는 제약이 없어 예약어도 사용할 수 있다! (ex. for, let...)
문자형, 심볼형(https://ko.javascript.info/symbol) 모두 프로퍼티 키가 될 수 있다.

문자형이나 심볼형이 아닌 값은 문자열로 자동 형 변환된다.

<script>
  let obj = {
    0: "test" // 프로퍼티 키인 0이 문자열로 형변환 되어 "0": "test"로 인식된다.
  };

  // 숫자 0이 문자열 "0"으로 변환되어 두 얼럿 창은 같은 프로퍼티에 접근한다.
  alert( obj["0"] ); // test
  alert( obj[0] ); // test (동일한 프로퍼티)
</script>

다만 한가지 제약이 있다면 __proto__ 라는 이름은 프로퍼티 키로 쓸 수 없다!
__proto__에 관한 내용은 '프로토타입 상속' 파트(https://ko.javascript.info/prototype-inheritance)에서 다룬다고 한다.


프로퍼티 존재 여부르 확인하는 'in' 연산자

자바스크립트는 없는 프로퍼티에 접근해도 에러가 발생하지 않고 undefined를 반환한다.

<script>
  let user = { name: "lee", age: 45 };

  alert( "age" in user ); // user.age가 존재하므로 true를 반환.
  alert( "blabla" in user ); // user.blabla는 존재하지 않으므로 false를 반환.
</script>

in 앞에 프로퍼티 키를 쓸때는 따옴표를 잊으면 안된다. 따옴표를 잊으면 동명의 변수에 접근하게 될 수 있다!

in은 프로퍼티 값이 undefined인 것과 상관 없이 해당 프로퍼티 자체가 존재하느냐를 검출할 수 있다.

<script>
  let obj = {
    test: undefined
  };

  alert( obj.test ); // 값이 undefined이므로, alert창에 undefined가 출력된다.

  alert( "test" in obj ); // `in`을 사용하면 프로퍼티 유무를 제대로 확인해 true가 출력된다.
  //값이 undefined인 거지 test 라는 프로퍼티가 존재하니까!
</script>

예시에서는 undefined만 다뤘는데 null도 마찬가지다.

in 외에도 객체가 비었는지 확인해주는 isEmpty() 함수가 있다

isEmpty(객체)

for...in 반복문

<script>
for (변수 in 객체) {
  // 각 프로퍼티 키(key, 위에서는 변수라고 기재)를 이용하여 본문(body)을 실행한다.
}
</script>

for...in 반복문은 위와 같이 사용하고 인라인 문법으로 선언된 변수로 in 뒤에 쓰인 객체의 key를 모두 읽어온다.

<script>
  let user = {
    name: "lee",
    age: 45,
    isAdmin: true
  };

  for (let key in user) {
    // 키
    alert( key );  // name, age, isAdmin
    
    // 키에 해당하는 값
    alert( user[key] ); // lee, 45, true
  }
</script>

위 예시를 보면 for...in 반복문도 일반 for 반복문처럼 인라인 문법으로 let key 라는 반복 변수를 선언했다.
key 외에 다른 이름으로 선언해도 문제 없다.


객체 정렬 방식

객체 안의 프로퍼티들 중 정수인 프로퍼티(integer property)는 숫자순으로 자동 정렬되고, 그 외의 프로퍼티는 객체에 추가한 순서 그대로 정렬된다.

<script>
//예시)
  let codes = {
    "49": "독일",
    "41": "스위스",
    "44": "영국",
    // ..,
    "1": "미국"
  };

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

[정수 프로퍼티 주의사항 ]
문자열 "49"는 정수로 변환하거나 변환한 정수를 다시 문자열로 바꿔도 변형이 없기 때문에 정수 프로퍼티이다. 하지만 '+49’와 '1.2’는 정수 프로퍼티가 아니다.

// 함수 Math.trunc는 소수점 아래를 버리고 숫자의 정수부만 반환.
alert( String(Math.trunc(Number("49"))) ); // '49'. 기존에 입력한 값과 같으므로 정수 프로퍼티입니다.
alert( String(Math.trunc(Number("+49"))) ); // '49'가 출력되지만 기존에 입력한 값(+49)과 다르므로 정수 프로퍼티가 아니다.
alert( String(Math.trunc(Number("1.2"))) ); // '1'이 출력되지만 기존에 입력한 값(1.2)과 다르므로 정수 프로퍼티가 아닙니다.

프로퍼티 값으로 숫자를 넣는데 숫자순으로 출력되는 것이 아니라 원하는 순서대로 출력되게 하고 싶다면 위의 방법을 이용하여 정수처럼 보이지만 정수가 아닌 값으로 선언하는 방법이 있다.

<script>
  let codes = {
    "+49": "독일",
    "+41": "스위스",
    "+44": "영국",
    // ..,
    "+1": "미국"
  };

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

위에서 살펴본 객체들은 '순수 객체'라고 불리는 일반 객체고 자바스크립트에는 일반 객체 외에도 Array, Date, Error 등 다양한 객체들이 있다. (Array 와 Date 는 독립적인 자료형이 아니고 '객체형'에 속한다.)

profile
하고 싶은 게 너무 많습니다.

0개의 댓글

관련 채용 정보