221207 TIL

오늘 한 일

  • 자바스크립트 완벽가이드 ~156p

객체 소개

  • 객체는 프로퍼티의 순서없는 집합
  • 자바스크립트의 객체는 프로토타입으로 불리는 다른 객체에서 프로퍼티를 상속하기도 한다.
  • 문자열, 숫자, 심벌, true, false, null, undefined가 아닌 값은 전부 객체이다.
    • 문자열, 숫자, 불은 객체가 아니지만 불변인 객체처럼 행동할 수도 있다.
  • 객체는 가변이며 값이 아닌 참조로 조작한다.
    • let y = x; 코드에서 변수 y는 객체 사본(X) 같은 객체 참조(O)
  • 객체를 통해 하는 일 생성, 검색, 삭제, 테스트, 프로퍼티 열거
  • 객체에서 직접 정의한 프로퍼티와 프로토타입 객체에서 상속한 프로퍼티를 구분해야 할 때가 있는데, 상속되지 않은 프로퍼티를 자체 프로퍼티(own property)라고 한다.
  • 프로퍼티 속성
    • 쓰기 가능
    • 열거 가능
    • 변경 가능

    *️⃣  내장 객체의 프로퍼티 중 상당수는 읽기 전용이거나 열거/변경 불가

객체 생성

1) 객체 리터럴

  • 객체 리터럴을 평가할 때마다 새 객체가 만들어진다.
  • 반복적으로 호출되는 함수나 루프 바디 안에 객체 리터럴이 있다면, 새 객체를 여러 개 만들 수 있다.
    • 프로퍼티 값 역시 매번 달라질 수 있다.
let empty = {};
let book = {
	"main title": "JavaScript",
	"sub-title": "The Definitive Guide",
	author: {
		first: "hwang",
		surname: "yunjin"
	}, // 객체 리터럴 마지막 프로퍼티 뒤에 콤마를 추가할 수 있다.
	// 문법 에러를 초래할 가능성이 줄어 들어 이 방법을 사용하는 사람도 있다.
};

2) new

  • new 키워드 뒤에는 반드시 함수 호출이 있어야 한다.
  • 이런 형태로 사용하는 함수를 생성자라고 부른다.
    • 자바스크립트의 내장 타입에도 생성자가 있다.
    • 직접 생성자 함수를 만들어 객체를 초기화 할 수도 있다.
let o = new Object(); // 빈 객체 생성
let d = new Date(); // 현재 시간을 나타내는 Date 객체 생성

3) 프로토타입

  • 자바스크립트 객체 대부분은 자신과 연결된 두 번째 객체를 갖는다.
    • 두번째 객체를 프로토타입이라고 한다.
    • 첫번째 객체는 프로토타입에서 프로퍼티를 상속한다.
  • 객체 리터럴을 사용해 생성한 객체는 모두 Object.prototype 프로토타입 객체를 갖는다.
  • new 키워드와 생성자를 사용해 만든 객체는 생성자 함수의 prototype 프로퍼티 값을 프로토타입으로 사용한다.
    • new Object()로 생성한 객체 ⇒ Object.prototype 상속
    • new Array()로 생성한 객체 ⇒ Object.Array 상속
    • new Date()로 생성한 객체 ⇒ Object.Date 상속

*️⃣  거의 모든 객체에 프로토타입이 있지만 prototype 프로퍼티가 있는 객체는 비교적 적다.

  • Object.prototype은 프로토타입이 없는 드문 객체 중 하나이다.
  • 다른 프로토타입 객체는 내장 생성자 대부분에 Object.prototype에서 상속하는 프로토타입이 있다.
    • new Date()로 생성한 Date 객체는 Date.prototype과 Object.prototype 양쪽에서 프로퍼티를 상속한다.
    • 이렇게 이어지는 프로토타입 객체 사이의 연결을 프로토타입 체인이라고 부른다.

image

image

- constructor는 Date()이지만 [[Prototype]]은 Object

![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/2611dc00-9444-4b2a-aaeb-01a5b717a0b3/Untitled.png)

- __proto__가 null

4) Object.create()

  • 첫번째 인자를 프로토타입 삼아 새 객체를 생성한다.
  • 두번째 인자는 새 객체의 프로퍼티를 설명하는 인자를 받을 수 있다. → ?
let o1 = Object.create({x: 1, y: 2});
o1.x + o1.y // => 3
  • 인자로 null을 전달해 프로토타입이 없는 객체를 생성할 수도 있지만, 이렇게 생성된 객체는 아무것도 상속하지 않으며 toString()과 같은 기본 메서드조차 없다.
let o2 = Object.create(null);

image

  • 객체 리터럴이나, new 연산자를 사용한 것처럼 일반적인 빈 객체를 만들고 싶다면 이렇게 한다.
let o3 = Object.create(Object.prototype);

image

*️⃣  Object.create()를 사용하는 목적 중 하나  : 서드 파티 라이브러리에서 (악의적인 의도가 없더라도) 객체를 변경하는 사고를 막는 것

let o = { x: "don't change this value" };
library.function(Object.create(o)); // 의도치 않은 변경에 대한 방어 역할