[딥다이브 스터디] 2주차 (2)

10. 객체 리터럴

10.1 객체란?

자바스크립트는 객체 기반 프로그래밍 언어
원시 값을 제외한 나머지 값은 모두 객체

원시타입객체타입
단 하나의 값다양한 타입의 값을 하나의 단위로 구성한 복합적인 자료구조
변경 불가능변경 가능한 값

자바스크립트에서 사용할 수 있는 모든 값 = 프로퍼티 값

  • 일급 객체인 함수 포함
  • 프로퍼티 값이 함수인 경우 = 메서드

객체 = 프로퍼티 + 메서드
0개 이상의 프로퍼티로 구성된 집합

  • 프로퍼티 : 키와 값으로 구성되며, 객체의 상태를 나타내는 값(data)
  • 메서드 : 프로퍼티를 참조하고 조작할 수 있는 동작

자바스크립트는 객체 지향 언어?
객체 지향 언어 (x) 객체 지향 프로그래밍이 가능한 언어 (o)

함수와 객체는 분리해서 볼 수 없음

10.2 객체 리터럴에 의한 객체 생성

클래스 기반 객체지향 언어

  • 클래스를 사전에 정의, 필요한 시점에 new 연산자와 함께 생성자를 호출해 인스턴스 생성하는 방식으로 객체 생성
  • C++, Java

인스턴스

클래스에 의해 생성되어 메모리에 저장된 실체
객체 지향 프로그래밍에서의 객체 = 클래스 + 인스턴스
클래스는 인스턴스를 생성하기 위한 템플릿 역할

프로토타입 기반 객체지향 언어

  • 다양한 객체 생성 방법 지원
    • 객체 리터럴 -> 가장 일반적이고 간단한 방법
    • Object 생성자 함수
    • 생성자 함수
    • Object.create 메서드
    • 클래스
  • JavaScript

객체 리터럴

리터럴 : 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법

객체 리터럴 : {} 를 이용해 0개 이상의 프로퍼티를 정의하며 객체를 생성하는 방법
변수가 할당되는 시점에 자바스크립트 엔진은 객체 리터럴을 해석해 객체를 생성
객체 리터럴의 중괄호 !== 코드 블록 -> 자체 종결성 X 세미콜론을 붙여줘야 함.

객체 리터럴을 제외한 객체 생성 방식은 모두 함수를 사용해 객체를 생성

10.3 프로퍼티

프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 또는 심벌 값

  • 식별자 네이밍 규칙을 따르지 않는 이름에는 반드시 따옴표를 사용해야 함
    • minjuKim : 15 ✅
    • minju kim : 15 ❌
    • "minju-kim" : 15 ✅
  • 동적으로 생성하기 위해선 대괄호 사용
    • obj[key] = minju // key = kim 이라는 변수일 때 {kim : minju} 객체 생성
  • 문자열이나 심벌 값 이외의 값을 사용하면 암묵적 타입 변환을 통해 문자열로 치환
  • 예약어를 사용할 수 있으나 권장되지 않음
  • 이미 존재하는 키를 중복 선언시, 나중에 선언한 키가 이전 키의 값을 덮어씀

프로퍼티 값 : 자바스크립트에서 사용할 수 있는 모든 값
-> 내장함수도 메서드

프로퍼티는 쉼표로 구분

10.5 프로퍼티 접근

프로퍼티에 접근하는 방법
1. 마침표 프로퍼티 접근 연산자(.) : 마침표 표기법
2. 대괄호 프로퍼티 접근 연산자([]) : 대괄호 표기법
대괄호 안에 들어가는 키는 무조건 따옴표로 감싸줘야함
감싸지 않고 참조하는 경우 식별자로 해석

객체에 존재하지 않는 프로퍼티 접근 시 undefined 반환

프로퍼티 키가 식별자 네이밍 규칙을 준수하는 경우
-> 두 표기법 모두 사용 가능
-> 아닌 경우, 대괄호 표기법만 사용 가능 (숫자로 이뤄진 문자열인 경우 제외)

❌
person.1
person.'1'

✅
person.[1]
person.['1']

person.last-name

node.js -> ReferenceError
브라우저 -> NaN (혹은 window 프로퍼티에 저장된 name 값)
person.last-name의 변수에 따옴표가 없는 경우, person 객체의 프로퍼티인 last에서 name이라는 변수를 빼는 코드(person.last - name)로 해석됨.
person.last 라는 객체가 없다면 undefined를 리턴하고, name이라는 변수를 찾기 시작함
이 때, node환경에서는 name이라는 변수가 없으니 에러가 발생하지만
브라우저 환경에서는 window객체에 name이라는 프로퍼티가 존재
해당 프로퍼티는 문자열이지만 - 숫자 연산자를 사용했으니 name 변수는 암묵적으로 숫자형으로 치환 - 하지만 숫자데이터가 아니니 결과값으로 NaN 출력

10.6 프로퍼티 값 갱신

이미 존재하는 프로퍼티에 값 할당 -> 값 갱신

10.7 프로퍼티 동적 생성

존재하지 않는 프로퍼티에 값을 할당 -> 동적으로 프로퍼티 생성

10.8 프로퍼티 삭제

delete 연산자를 이용해 프로퍼티 삭제 가능

let person = {
 name : "minju"
}
 
console.log(person.name) //minju

delete person.name;

console.log(person.name) // undefined

10.9 ES6에서 추가된 객체 리터럴의 확장 가능

10.9.1 프로퍼티 축약 표현

ES6에서는 프로퍼티 값으로 변수를 사용하는 경우, 변수 이름과 프로퍼티 키가 동일한 이름일 때 키를 생략할 수 있음

let x = 1, y = 2;

const obj = {x, y};

console.log(obj) // {x : 1, y : 2};

10.9.2 계산된 프로퍼티 이름

프로퍼티 키를 동적으로 생성하기 위해서

  • 표현식을 대괄호로 묶기
  • 문자열 또는 문자열 타입으로 변환 가능해야함
let i = 0;

obj["serial-" + ++i] = i; // es5
obj[`serial-${++i}`] = i; // es6
 

10.9.3 메서드 축약 표현


let obj = {
    func1 : function() {
        console.log("es5 grammar")
    }
    func2() {
        console.log("es6 grammar")
    }
}

위 예시처럼 es6 문법에서는 메서드를 축약형으로 할당 가능함.
이렇게 선언한 문법은 es5에서 프로퍼티에 함수를 할당하는 방식과 다르게 동작

11. 원시 값과 객체의 비교

원시 타입객체 타입
변경 불가능한 값변경 가능한 값
실제 값이 저장참조값이 저장
다른 변수에 할당 시 원시 값이 복사되어 저장참조값이 복사되어 저장
값에 의한 전달참조에 의한 전달

11.1 원시 값

11.1.1 변경 불가능한 값

한 번 생성된 원시값은 읽기 전용 값으로 변경될 수 없음

변수 값 변경의 의미
1. 원시 값을 재할당
2. 새로운 메모리 공간을 확보하고 재할당한 값을 저장
3. 변수가 참조하던 메모리 공간의 주소가 바뀜 (불변성)
따라서, 불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없음.

11.1.2 문자열과 불변성

원시 값을 저장하려면 확보해야 하는 메모리 공간의 크기를 결정해야 함
문자열은 다른 원시값과 달리 문자열이 구성된 문자의 갯수에 따라 메모리 공간의 크기가 결정됨. -> 자바스크립트는 개발자의 편의를 위해 원시 타입의 문자열 타입 제공

문자열은 유사배열객체이면서 이터러블 -> 배열과 유사하게 접근 가능
하지만 원본 데이터를 변경하는 것은 안됨 (재할당은 가능)

유사배열객체

  • 배열처럼 인덱스로 접근 가능
  • length 프로퍼티를 가짐

11.1.3 값에 의한 전달

변수에 원시값을 갖는 변수를 할당
-> 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달
= 값에 의한 전달

같은 값을 가지더라도 다른 메모리 공간에 저장된 별개의 값...?
같은 원시값을 참조하다가 한 변수에 재할당이 이뤄지면 새로운 메모리 공간에 재할당된 값 참조...?

변수에는 값이 전달되는 것이 아닌 메모리 주소가 전달
식별자 = 메모리 주소에 붙인 이름
전달된 메모리 주소를 통해 메모리 공간에 접근해 값을 참조하는 방식

두 변수의 원시값은 서로 다른 메모리 공간에 저장된 별개의 값이 되어 어느 한쪽에서 재할당을 통해 값을 변경하더라도 간섭할 수 없음

11.2 객체

객체는 동적으로 프로퍼티가 추가되고 삭제될 수 있기때문에 메모리의 크기를 미리 정할 수 없음.

자바스크립트 객체의 관리 방식

프로퍼티 키를 인덱스로 사용하는 해시테이블 방식 (100%는 아니고 비슷)
이는 객체를 생성하기 전 미리 프로퍼티와 메서드가 정해져 있어 메모리가 픽스되는 클래스 기반 프로그래밍 언어와 다르게 비효율적인 방식
따라서 v8 엔진에서는 프로퍼티에 효율적으로 접근하기 위해 히든 클래스 방식 선택

11.2.1 변경 가능한 값

객체를 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근 - 참조값에 접근
참조값 = 객체가 저장된 메모리 공간의 주소

객체를 할당한 변수

  • 재할당 없이 프로퍼티를 동적으로 추가 가능
  • 프로퍼티 값 갱신 가능
  • 프로퍼티 삭제 가능

여러 개의 식별자가 하나의 객체를 공유할 수 있다는 단점 존재

11.2.2 참조에 의한 전달

객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조값이 복사되어 전달

두 개의 객체가 하나의 객체를 공유하기 때문에 한 쪽을 수정하면 다른 한 쪽에도 영향

값에 의한 전달과 참조에 의한 전달

두 방식 모두 식별자가 기억하는 메모리 공간에 대한 주소값을 가지고 있고 그 주솟값이 참조하는 값이 원시값이냐 참조값이냐의 차이만 존재

객체는 타입 관계 없이 다른 메모리 공간에서 참조되기 때문에 동등 비교와 일치 비교와 관계 없이 서로 다른 값

좋은 웹페이지 즐겨찾기