본문 바로가기

2022-2 웹개발 스터디

[모던 JS] CH10 객체 리터럴, CH11 원시 값과 객체의 비교

CH10. 객체 리터럴

10.1 객체란?

- 원시 타입의 값은 변경 불가능한 값이지만 객체 타입의 값인 객체는 변경이 가능한 값

- 객체는 0개 이상의 프로퍼티로 구성된 집합으로 프로퍼티는 키와 값으로 구성됨

- 객체는 프로퍼티와 메서드로 구성된 집합체

! 프로퍼티: 객체의 상태를 나타내는 값

! 메서드: 프로퍼티를 참조하고 조직할 수 있는 동작

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

다양한 객체 생성 방법을 지원함

- 객체 리터럴

- Object 생성자 함수

- 생성자 함수

- Object.create 메서드

- 클래스

var person = {
    name: 'Lee',
    sayHello: function () {
        console.log(`Hello! my name is ${this.name}.`);
    }
};

console.log(typeof person);
console.log(person);

// 만약 중괄호 내에 프로퍼티를 정의하지 않으면 빈 객체가 생성됨
var empty = {};
console.log(typeof empty);

 

- 객체 리터럴의 중괄호는 코드 블록을 의미하지 않음

- 코드 블록의 닫는 중괄호 뒤에는 세미 콜론을 붙이지 않음

- 객체 리터럴은 값으로 평가되는 표현식, 객체 리터럴의 닫는 중괄호 뒤에는 세미콜론을 붙임

10.3 프로퍼티

- 객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구성됨

var person = {
    name: 'Lee';
    age: 20
};

 

- 프로퍼티를 나열할 때는 쉼표로 구분함

- 일반적으로 마지막 프로퍼티 뒤에는 쉼표를 사용하지 않으나 사용해도 좋음

- 프로퍼티 키는 프로퍼티 값에 접근할 수 있는 이름으로서 식별자 역할을 함

- 식별자 네이밍 규칙을 따르지 않는 이름에는 반드시 따옴표를 사용해야 함

var person = {
    firstName: 'Ung-mo', // 식별자 네이밍 규칙을 준수하는 프로퍼티 키
    'last-name': 'Lee'   // 식별자 네이밍 규칙을 준수하지 않는 프로퍼티 키
};

 

- 프로퍼티 키에 문자열이나 심벌 값 외의 값을 사용하면 암묵적 타입 변환을 통해 문자열이 됨

- 예로, 프로퍼티 키로 숫자 리터럴을 사용하면 따옴표는 붙지 않지만 내부적으로는 문자열로 변환됨

var foo = {
    0:1,
    1:2,
    2:3
};

console.log(foo);

 

- var, function과 같은 예약어를 프로퍼티 키로 사용해도 에러가 발생하지는 않지만, 예상치 못한 에러가 발생할 수 있으므로 권장하지 않음

- 이미 존재하는 프로퍼티 키를 중복 선언하면 나중에 선언한 프로퍼티가 먼저 선언한 프로퍼티를 덮어씀 -> 에러가 발생하지 않음

10.4 메서드

-> 객체에 묶여있는 함수

-> 12장에서 계속

10.5 프로퍼티 접근

- 마침표 프로퍼티 접근 연산자를 사용하는 마침표 표기법

- 대괄호 프로퍼티 접근 연산자를 사용하는 대괄호 표기법

 

: 프로퍼티 키가 식별자 네이밍 규칙을 준수하는 이름인 경우 두 표기법을 모두 사용할 수 있음

: 대괄호 표기법을 사용하는 결루 대괄호 프로퍼티 접근 연산자 내부에 지정하는 프로퍼티 키는 반드시 따옴표로 감싼 문자열

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

var person = {
    name: 'Lee'
};

console.log(person.age); // undefined

 

- 프로퍼티 키가 식별자 네이밍 규칙을 준수하지 않는 이름이 아니면 반드시 대괄호 표기법을 사용해야 함

- 단 프로퍼티 키가 숫자로 이뤄진 문자열인 경우 따옴표를 생략할 수 있음

10.6 프로퍼티 값 갱신

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

var person = {
    name: 'Lee'
};

person.name = 'kim'

10.7 프로퍼티 동적 생성

- 존재하지 않는 프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성되어 추가되고 프로퍼티 값이 할당됨

var person = {
    name: 'Lee'
};

person.age = 20

10.8 프로퍼티 삭제

delete 연산자 이용

: 이때 delete 연산자의 피연산자는 프로퍼티 값에 접근할 수 있는 표현식이어야 함

: 만약 존재하지 않는 프로퍼티를 삭제하면 아무런 에러 없이 무시됨

CH11. 원시 값과 객체의 비교

- 원시 타입의 값은 변경 불가능한 값

- 객체 타입의 값은 변경 가능한 값

- 원시 값을 변수에 할당하면 변수에는 실제 값이 저장됨

- 객체를 변수에 할당하면 참조 값이 저장됨

- 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달됨(값에 의한 전달)

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

11.1 원시값

11.1.1 변경 불가능한 값

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

- 원시 값의 특성은 데이터의 신뢰성을 보장함

 

- 원시 값은 변경 불가능한 값이기 때문에 직접 변경할 수 없음

- 따라서 변수 값을 변경하기 위해 원시 값을 재할당하면 새로운 메모리 공간을 확보하고 재할당한 값을 저장한 뒤 변수가 참조하던 메모리 공간의 주소를 변경함 -> 불변성

- 불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없음

11.1.2 문자열과 불변성

- 자바스크립트는 개발자의 편의를 위해 원시 타입인 문자열 타입을 제공함

- 문자열은 원시 타입이며 변경이 불가능함 (문자열이 생성된 이후에는 변경할 수 없음을 의미)

- 그러나 변수에 새로운 문자열을 재할당하는 것은 가능함

:기존 문자열을 변경하는 것이 아니라, 새로운 문자열을 새롭게 할당하는 것이기 때문!

11.1.3 값에 의한 전달

- 엄격하게 표현하면 변수에는 값이 전달되는 것이 아니라, 메모리 주소가 전달됨

- 변수와 같은 식별자는 값이 아니라 메모리 주소를 기억하고 있음

- 식별자로 값을 구별해서 식별한다는 것은 식별자가 기억하고 있는 메모리 주소를 통해 메모리 공간에 저장된 값에 접근할 수 있다는 것을 의미함

: 식별자는 메모리 주소에 붙인 이름

11.2 객체

- 객체는 프로퍼티의 개수가 정해져 있지 않음

11.2.1 변경 가능한 값

- 객체 타입의 값은 변경 가능한 값

- 변수는 이 참조 값을 통해 객체에 접근할 수 있음

- 원시 값을 할당한 변수를 참조하면 메모리에 저장되어 있는 원시 값에 접근함

- 객체를 할당한 변수를 참조하면 메모리에 저장되어 있는 참조 값을 통해 실제 객체에 접근함

- 객체를 변경할 때마다 원시 값처럼 이전 값을 복사해서 새롭게 생성하면 메모리의 효율적 소비가 어렵고 성능이 나빠짐

- 객체는 이런 구조적 단점에 따른 부작용이 존재함 -> 원시 값과는 다르게 여러 개의 식별자가 하나의 객체를 공유할 수 있다는 것

11.2.2 참조에 의한 전달

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

- 원본 person과 사본 copy

- 위의 예제에서 저장된 메모리 주소는 다르지만, 동일한 참조 값을 가짐( 동일한 객체를 가리키는 것)

- 즉, 두 개의 식별자가 하나의 객체를 공유한다는 것

: 어느 한쪽에서 객체를 변경하면 서로 영향을 주고 받음