오늘 한 일
- 자바스크립트 완벽가이드 ~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 양쪽에서 프로퍼티를 상속한다.
- 이렇게 이어지는 프로토타입 객체 사이의 연결을
프로토타입 체인
이라고 부른다.
- 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);
- 객체 리터럴이나, new 연산자를 사용한 것처럼 일반적인 빈 객체를 만들고 싶다면 이렇게 한다.
let o3 = Object.create(Object.prototype);
*️⃣ Object.create()를 사용하는 목적 중 하나 : 서드 파티 라이브러리에서 (악의적인 의도가 없더라도) 객체를 변경하는 사고를 막는 것
let o = { x: "don't change this value" };
library.function(Object.create(o)); // 의도치 않은 변경에 대한 방어 역할