객체를 소프트웨어의 세계에서 표현하기 위해 객체의 핵심적인 개념 또는 기능만을 추출하는 추상화를 통해 모델링하려는 패러다임
관계성있는 객체들의 집합
별도의 역할이나 책임을 갖는 작은 독립적인 기계 또는 부품
자바스크립트: 명령형, 함수형, 프로토타입 기반 객체지향 언어.
let obj = { "name": "lee" }let obj = new Object(); obj.name = "lee";function F() {}
let obj = new F();
obj.name = "lee";ES6에서 클래스가 도입됨. 새로운 객체지향 모델이 아니라 클래스도 사실 함수이고 기존 프로토타입 기반 패턴의 syntactic sugar(더 나은 가독성과 표현력을 위한 문법)임.
function Person(name) {
this.name = name;
this.setName = function(name) { this.name = name; };
this.getName = function() { return this.name; };
}
const p1 = new Person("david");
console.log(p1.getName());
위와 같이 생성자 함수를 구현하고 new 연산자로 인스턴스를 생성할 수 있음.
하지만 위의 방법대로 여러 인스턴스를 생성하게 되면 인스턴스마다 메소드(getName, setName)이 중복되어 생성됨 --> 메모리 낭비
프로토타입 체인: 프로토타입을 통해 직접 객체를 연결하는 것. (모든 객체는 프로토타입(객체)이라는 내부 링크를 가지고 있음)
function Person(name) { this.name = name; }
Person.prototype.setName = function (name) { this.name = name; }
Person.prototype.getName = function () { return this.name; }

프로토타입 객체에 메소드 추가하는 방식
// Function.prototype == 생성자 함수의 프로토타입
Function.prototype.method = function (name, func) {
// 프로토타입의 name(메소드 이름)에 func(메소드 본체) 할당
if (!this.prototype[name]) {
this.prototype[name] = func;
}
};
function Person(name) { this.name = name; }
Person.method('setName', function (name) { this.name = name; });
Person.method('getName', function () { return this.name; });
상속 구현 방식 두 가지:
기본적으로 프로토타입을 통해 상속을 구현함(프로토타입을 통해 객체가 다른 객체로 직접 상속됨)
let Parent = (function () {
function Parent(name) { this.name = name; }
Parent.prototype.sayHi = function () { console.log("hi " + this.name); };
return Parent;
}());
let Child = (function () {
function Child(name) { this.name = name; }
Child.prototype = new Parent();
Child.prototype.sayHi = function () { console.log("hi" + this.name); };
Child.prototype.sayBye = function () { console.log("bye " + this.name); };
return Child;
}());

Child에서 구현한 sayHi와 sayBye 모두 Parent 생성자 함수의 인스턴스 에 위치됨.(Child.prototype == new Parent()이기 때문에)
의사 클래스 패턴 상속은 구동 상 문제가 없지만 문제가 있음.
Object.create() 메소드를 사용하여 객체에서 다른 객체로 직접 상속을 구현하는 방식. 의사 클래스 패턴 상속 구현에서 생기는 문제가 해결됨.
let Parent = (function () {
function Parent(name) { this.name = name; }
Parent.prototype.sayHi = function () { console.log("hi " + this.name); };
return Parent;
}());
let child = Object.create(Parent.prototype);
child.name = 'child';
child.sayHi();

의사 클래스 패턴 상속 방식과 다르게 child가 Parent.prototype을 직접 가리킬 수 있음.
또한, 객체리터럴 패턴으로 생성한 객체에도 상속을 사용할 수 있음.
let parent = {
name: 'parent',
sayHi: function() { console.log("hi " + this.name); }
};
let child = Object.create(parent);
child.name = 'child';
parent.sayHi();
child.sayHi();

if (!Object.create) {
Object.create = function (o) {
function F() {} // 1
F.prototype = o; // 2
return new F(); // 3
};
}

캡슐화: 정보 은닉(관련있는 멤버 변수/메소드를 하나의 틀에 담고 외부에 공개될 필요가 없는 정보를 숨기는 것)
ex) 클래스 기반 언어의 public, private 등
let person = function(arg) {
var name = arg; // private
this.name = arg; // public
// 클로저로서 private 변수 접근 가능
return {
getName: function() { return name; },
setName: function(arg) { name = arg; }
}
}
let p1 = person("Lee");
let name = p1.getname();
p1.setName("Kim");
let Person = function() {
let name;
let F = function(arg) { name = arg ? arg : ''; };
F.prototype = {
getName: function() { return name; },
setName: function(arg) { name = arg; }
};
return F;
}();
