Index
③ 프로토타입 객체
④ 리터럴 표기법에 의해 생성된 객체의 생성자 함수와 프로토타입
⑦ 프로토타입 체인
⑪ 직접 상속
⑭ 프로퍼티 열거
“자바스크립트는 명령형(imperative), 함수형(functional), 프로토타입 기반(prototype-based) 객체지향 프로그래밍(OOP, Object Oriented Programming)을 지원하는 멀티 패러다임 프로그래밍 언어다.”
1. 객체지향 프로그래밍
객체지향 프로그래밍은 프로그램을 명령어 또는 함수의 목록으로 보는 전통적인 명령형 프로그래밍의 절차지향적 관점에서 벗어나 여러개의 독립적 단위, 즉 객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임을 말한다. - Ungmo Lee, DeepDive Javascript p.260
객체는 상태데이터와 동작을 하나의 논리적인 단위로 묶은 복합적인 자료구조라고 할 수 있다.
객체의 상태 데이터를 프로퍼티(property), 동작을 메서드(method)라 부른다.
각 객체는 고유의 기능을 갖는 독립적인 부품으로 볼 수 있지만 자신의 고유한 기능을 수행하면서 다른 객체와 관계성을 가질 수 있다. 다른 객체와 메시지를 주고 받거나 데이터를 처리할 수 있다. 또는 다른 객체의 상태 데이터나 동작을 상속받아 사용하기도 한다.
2. 상속과 프로토타입
프로토타입 기반 상속의 핵심 목표는 ‘코드 재사용’, ‘메모리 절약’, ‘동적 확장’이다.
- 코드 재사용: 공통된 메서드나 속성을 여러 객체에 중복 정의하지 않고 재사용할 수 있도록 한다.
- 메모리 절약: 공통 메서드를 개별 객체에 복사하지 않고 프로토타입 체인에서 공유하기 때문에 효율적입니다.
- 동적 확장: 프로토타입에 새로운 메서드나 속성을 추가하면 이를 상속받는 객체들이 즉시 사용하 수 있습니다.
// 생성자 함수
function Circle(radius) {
this.radius = radius;
}
/*
Circle 생성자 함수가 생성한 모든 인스턴스가
getArea 메서드를 공유해서 사용할 수 있도록 프로토타입에 추가한다.
프로토타입은 Circle 생성자 함수의 prototype 프로퍼티에 바인딩되어 있다.
*/
Circle.prototype.getArea = function () {
return Math.PI * this.radius ** 2;
};
const circle1 = new Circle(1);
const circle2 = new Circle(2);
console.log(circle1.getArea === circle2.getArea);
console.log(circle1.getArea());
console.log(circle2.getArea());
3. 프로토타입 객체
🧐 Q. prototype
프로퍼티는 생성자함수가 자신이 생성할 객체의 프로토타입을 할당하기 위해 사용되는데 생성된 객체가_proto_
로 접근가능한데 왜 필요한걸까?
prototype
속성은 생성자 함수가 생성할 여러 객체들이 공통적으로 사용할 프로토타입 객체를 정의할 수 있도록 합니다. 이는 코드 재사용과 메모리 효율성을 위해 필요합니다.
// 생성자 함수
function Person(name) {
this.name = name;
}
const me = new Person("Lee");
// 결국 Person.prototype과 me.__proto__는 결국 동일한 프로토타입을 가리킨다.
console.log(Person.prototype === me.__proto__); // true

Property of a function object
Ungmo Lee. (2020). Modern Javascript DeepDive. wikibooks. p.271.
4. 리터럴 표기법에 의해 생성된 객체의 생성자 함수와 프로토타입
리터럴 표기법에 의한 객체 생성방식은 인스턴스를 생성하지 않는 객체 생성방식이다.
// 객체 리터럴
const obj = {};
// 함수 리터럴
const add = function (a, b) {
return a + b;
};
// 배열 리터럴
const arr = [1, 2, 3];
// 정규 표현식 리터럴
const regexp = /is/gi;
🧐 Q. 리터럴 표기법에 의해 생성된 객체의 경우 프로토타입의 constructor 프로퍼티가 가리키는 생성자 함수가 반드시 객체를 생성한 생성자 함수라고 단정할 수 있을까?
// obj 객체는 Object 생성자 함수로 생성한 객체가 아니라 객체 리터럴로 생성했다.
const obj = {};
// 하지만 obj 객체의 생성자 함수는 Object 생성자 함수다.
console.log(obj.constructor === Object); // true

Object Constructor Function
Ungmo Lee. (2020). Modern Javascript DeepDive. wikibooks. p.274.

Object Literal Evaluation
Ungmo Lee. (2020). Modern Javascript DeepDive. wikibooks. p.275.

Comparison of Object Constructor Function and Object Literal evaluation
JayTak
1. 빈 객체 생성
// Object 생성자 함수
let obj = new Object();
console.log(obj); // {}
// 객체 리터럴
let obj = {};
console.log(obj); // {}
2. 속성 정의
// Object 생성자 함수
let obj = new Object();
obj.a = 1;
obj.b = 2;
console.log(obj); // {a: 1, b: 2}
// 객체 리터럴
let obj = {a: 1, b: 2};
console.log(obj); // {a: 1, b: 2}
3. 계산된 속성이름
// Object 생성자 함수
let key = "dynamicKey";
let obj = new Object();
obj[key] = 42;
console.log(obj); // { daynamic: 42 }
// 객체 리터럴
let key = "dynamicKey";
let obj = { [key]: 42 };
console.log(obj); // { dynamic: 42 }
4. 원시 값 처리
// Object 생성자 함수
console.log(Object(42)); // Number{42}
conosle.log(Object("hello")); // String{"hello"}
// 객체 리터럴
let obj = { a: 1 };
console.log(obj); // { a: 1 }
5. 프로토타입 생성시점
추후 업데이트 예정
6. 객체 생성 방식과 프로토타입의 결정
Object
생성자 함수에 의해 생성된 객체의 프로토타입
=> Object 생성자 함수에 의해 생성된 객체 obj는 Object.prototype을 프로토타입으로 갖게되며, 이로써 Object.prototype을 상속받는다.
const obj = new Object();
obj.x = 1;
cosole.log(obj.constructor === Object); // true
console.log(obj.hasOwnProperty("x")); // true
생정자 함수에 의해 생성된 객체의 프로토타입
=> Person 생성자 함수를 통해 생성된 모든 객체는 프로토타입에 추가된 sayHello 메서드를 상속받아 자신의 메서드처럼 사용할 수 있다.
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function () {
console.log(`Hi! My name is ${this.name}`);
};
const me = new Person("Lee");
const you = new Person("Tak");
me.sayHello(); // Hi! My name is Lee
you.sayHello(); // Hi! My name is Tak
7. 프로토타입 체인
추후 업데이트 예정
8. 오버라이딩과 프로퍼티 섀도잉
추후 업데이트 예정
9. 프로토타입의 교체
생성자 함수에 의한 프로토타입 교체

Prototype replacement by constructor function
Ungmo Lee. (2020). Modern Javascript DeepDive. wikibooks. p.291.
const Person = (function () {
function Person(name) {
this.name = name;
}
// 생성자 함수의 prototype 프로퍼티를 통해 프로토타입을 교체
Person.prototype = {
// constructor 프로퍼티와 생성자 함수 간의 연결을 설정
constructor: Person,
sayHello() {
console.log(`Hi! My name is ${this.name}`);
},
};
return Person;
})();
const me = new Person("Lee");
// constructor 프로퍼티가 생성자 함수를 가리킨다.
console.log(me.constructor === Person); // true
console.log(me.constructor === Object); // false
프로토타입으로 교체한 객체 리터럴에 constructor
프로퍼티를 추가하여 프로토타입의 constructor
프로퍼티를 되살린다.
인스턴스에 의한 프로토타입 교체

Prototype replacement by instance
Ungmo Lee. (2020). Modern Javascript DeepDive. wikibooks. p.293.
function Person(name) {
this.name = name;
}
const me = new Person("Lee");
// 프로토타입으로 교체할 객체
const parent = {
// constructor 프로퍼티와 생성자 함수 간의 연결을 설정
constructor: Person,
sayHello() {
console.log(`Hi! My name is ${this.name}`);
},
};
// 생성자 함수의 prototype 프로퍼티와 프로토타입 간의 연결을 설정
Person.prototype = parent;
// me 객체의 프로토타입을 parent 객체로 교체한다.
Object.setPrototype(me, parent); // ⭐️ 추가과정
// 위 코드는 아래의 코드와 동일하게 동작한다.
// me.__proto__ = parent;
me.sayHello();
// constructor 프로퍼티가 생성자 함수를 가리킨다.
console.log(me.constructor === Person); // ture
console.log(me.constructor === Object); // false
// 생성자 함수의 prototype 프로퍼티가 교체된 프로토타입을 가리킨다.
console.log(Person.prototype === Object.getPrototypeOf(me)); // true
프로토타입으로 교체한 객체 리터럴에 constructor
프로퍼티를 추가하고 생성자 함수의 prototype
프로퍼티를 재설정하여 파괴된 생성자 함수와 프로토타입 간의 연결을 되살려 보자.
10. instanceof 연산자
const Person = (function () {
function Person(name) {
this.name = name;
}
Person.prototype = {
sayHello() {
console.log(`Hi! My name is ${this.name}`);
},
};
return Person;
})();
const me = new Person("Lee");
console.log(me.constructor === Person); // false
// 하지만 Person.prototype을 새 객체로 대체하면, 새 객체는 기본적으로 constructor 프로퍼티를 가지지 않으므로, 프로토타입 체인을 따라 Object의 constructor를 참조하게 됩니다. 따라서, 원래의 생성자 함수와의 연결이 끊어지게 됩니다.
11. 직접상속
추후 업데이트 예정
12. 정적 프로퍼티/메서드
추후 업데이트 예정
13. 프로퍼티 존재 확인
추후 업데이트 예정
14. 프로퍼티열거
추후 업데이트 예정