컴퓨터 프로그래밍 방식 및 패러다임 중 하나
OOP는 프로그램을 여러개 독립된 단위, '객체'의 모임으로 인식한다.
객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다.
현실 세계의 모델을 코드로 옮기는데 유리하다. (직관적 코드 분석이 가능해짐)
소프트웨어 개발과 유지보수를 간편하게 하는 장점이 있다.
객체 지향 프로그래밍의 구성 요소 (Pseudoclassical 방식)
인스턴스
생성자
인스턴스를 생성하고 클래스 필드를 초기화하기 위한 특수한 메소드
*클래스 필드: 클래스 내부의 캡슐화된 변수. (데이터 멤버, 멤버 변수라고도 불림) attributes or properties
클래스 내에 한 개만 존재할 수 있다.
constructor를 생략하면 빈 객체를 생성한다. 따라서 프로퍼티는 동적으로 추가해야 한다.
클래스 필드의 생성과 초기화를 실행하기 때문에 클래스 필드를 초기화해야할 경우 생략해서는 안된다. (초기화: 처음 값의 할당)
new연산자와 함께 호출할 때 사용하는 이름은 클래스의 이름이 아닌 생성자의 이름이다.
선언식으로 정의한 클래스 이름은 constructor와 동일하다.
new 연산자 없이 호출할 수 없다.
클래스
객체지향 프로그램의 사용자 정의 데이터형
*파스칼 케이스를 사용하는 것이 일반적이다 (그러나 사용하지 않아도 에러가 발생되진 않는다)
자바스크립트에는 클래스가 없다
(다만, ES6에 추가된 class
문법도 실상은 함수이지만, 클래스 기반 언어에 익숙한 프로그래머들이 보다 더 친숙하게 사용할 수 있도록 추가됐다. )
클래스는 클래스 선언문 이전에는 참조할 수 없다. (함수보다 엄격함)
let, const 키워드로 선언한 변수처럼 호이스팅이 된다. (let은 선언 전 해당 변수를 호출하면 referenceError를 반환한다, var 호이스팅과 차이가 있다)
표현식으로도 클래스 선언문을 정의할 수 있다. 이는 함수의 표현식과 거의 동일하게 작동한다.
클래스 바디엔 메소드만 선언할 수 있다. 클래스 필드를 선언하면 문법 에러가 발생한다.
프로퍼티 (클래스 필드)
메서드
정적 메소드
static
키워드를 사용한다.
클래스의 인스턴스가 아닌 클래스 이름으로 호출한다.
this를 사용할 수 없다. (사용할 경우 인스턴스가 아닌 클래스를 가리킨다)
정적 메소드는 유틸리티 함수를 생성할 때 주로 사용한다.
(함수도 결국은 객체이고 다만 함수는 일반 객체와 달리 protype 프로퍼티를 갖는다. 이 프로퍼티는 함수 객체가 생성자로 사용될 때, 함수를 통해 생성된 객체의 부모 역할을 하는 프로토타입 객체를 가리킨다)
인스턴스의 proto, 생성자 함수의 protoype
프로토타입 메소드
객체지향 언어, 자바스크립트
자바스크립트는 프로토타입 기반 객체지향 언어다.
프로토타입 기반 프로그래밍
클래스가 필요없는 객체지향 프로그래밍 스타일. 프로토타입 체인과 클로저 등으로 객체 지향 언어의 상속, 캡슐화 등의 개념을 구현
getter / setter
getter
getter는 클래스 필드에 접근할 때마다 클래스 필드의 값을 조작하는 행위가 필요할 때 사용한다.
메소 이름 앞에 get
키워드를 사용해 정의한다. 반드시 어떠한 값을 반환해야 한다.
setter
set
키워드를 사용한다.var user = {
id: 'elin',
age: 7,
gender: 'female'
}
let method = { number: 2 }
let obj = Object.create(method);
console.log(obj.number) // 2
let method = {};
method.sum = function(){
this.result = this.number.reduce((a,c)=> a + c);
};
obj = Object.create(method);
obj.number = [1,2,3,4,5];
obj.sum();
console.log(obj.result) // 15
var user = new Object(); //{}
user.id = 'elin';
user.age = 7;
user.gender = 'female'
class Person{
constructor(id, age, gender){
this.id = id;
this.age = age;
this.gender = gender;
}
}
Person.prototype.exportInfo = function(){
console.log(`${this.id}라는 아이디를 가진 ${this.age}살의 ${this.gender} 입니다`);
}
let person1 = new Person('abce', 10, 'female')
person1.exportInfo() // abce라는 아이디를 가진 10살의 female 입니다
prototype 객체
원형이라는 뜻
생성자 함수로 만든 인스턴스 객체는 모두 프로토타입 메소드를 공유한다.
클래스 필드에도 메소드를 넣을 수 있다. 다만 그보다 프로토타입에 메소드를 할당하면 모든 인스턴스에서 해당 메소드를 공유하게 되므로, 불필요한 메모리 낭비가 방지된다.
때문에 어떤 경우엔 메소드 뿐 아니라 속성까지도 다 프로토타입에 넣기도 한다.
prototype 과 proto
인스턴스가 가지는 proto 객체
현재 person1 의 proto객체의 constructor는 클래스 person 이 담겨있다.
person1.__proto__.__proto__.constructor
엔 Object 가 담겨있다.
constructor는 생성자 함수 그 자체를 가리킨다.
prototype는 생성자 함수에 정의한 모든 객체가 공유한다.
__proto__
는 생성자 함수를 new 로 호출할 때, 인스턴스가 만들어질 때 정의해두었던 prototype를 참조한 객체다
prototype 은 생성자 함수에 사용자가 직접 넣는 것이고 (클래스이름.prototype.메소드이름 = 정의내용 과 같은 형식으로) __proto__
는 new를 호출 할 때 prototype을 참조하여 자동으로 만든다.
따라서 사용자는 prototype 을 신경쓰면 된다.
prototype, __proto__
, constructor의 관계
__proto__
는 같다.__proto__
의 constructor는 생성자 함수와 같다.참고:
https://poiemaweb.com/js-object
https://poiemaweb.com/es6-class
https://ko.wikipedia.org/wiki/
https://developer.mozilla.org/
https://www.zerocho.com/category/JavaScript/