javaScript는 프로토타입의 OOP이며, 처음부터 OOP를 생각하고 만들어진 언어는 아니다.
OOP는 보편적으로 많이 쓰이는 개발 방법론이기 때문에 프로토타입으로 OOP를 구현할 수 있도록 많은 노력을 하였고, 연구끝에 ES6에 Class를 이용한 OOP가 지원이 되었다.
OOP(Object-Oriented Programming)
: 객체 지향 언어
Instance
: constructor 함수로 만들어진 객체
constructor
: Class안에 있는 생성자 함수, 특정객체(new를 이용한)가 생성될때 실행되는 코드
__Proto__
: 프로토타입 링크 또는 프로토타입 체인이라고 불림, 부모의 프로토타입 객체를 참조함.
prototype
: 원형 객체, 모든 함수에 있는 속성(객체)
Object
: 최상위 객체로 모든 객체의 부모. 즉, 모든 객체는 Object.prototype을 상속받는다.
__proto__
의 참조방향(시각화)이미지 출처 : 오승환님 블로그
//부모 class
function Human(name) {
this.name = name; //constructor 함수
}
Human.prototype.sleep = function(){
return '자는중...'
}
//Human함수의 prototype 객체에 메소드를 생성할 수 있다.
let human1 = new Human('yong') // instance 객체
console.log(human1.sleep()) // 자는중...
//자식 class
function Student(name,age) {
Human.call(this,name)
this.age = age;
}
//Human class와 상속 관계 만드는 코드
Student.prototype = Object.create(Human.prototype)
Student.prototype.constructor = Student;
//
Student.prototype.learn = function(){
return '공부중...'
}
let student1 = new Student('jun',17)
console.log(student1.sleep()) // 자는중...
console.log(student1.learn()) // 공부중...
console.log(student1.age) // 17
console.log(student1.name) // 'jun'
위 코드처럼 작성하면 Human Class가 부모가 되고 Student Class가 자식이 되어 상속관계가 된다. console.log 값을 객체에서 찾을 수 없을 때 부모 프로토타입 객체를 참조하여 값이 출력된다. - 프로토타입 chain
prototype은 할당이 가능하기 때문에 상속 관계를 맺기 위해서 이렇게 할 수 있다.
Student.prototype = Human.prototype
하지만 이렇게 그냥 할당만 해버리면 문제가 생긴다. Student.prototype에 메소드를 생성하면 Human.prototype에도 메소드가 생성이 되버린다. 그래서 이 방법을 사용하면 된다.
Student.prototype = Object.create(Human.prototype)
Object.create()는 쉽게 생각해서 ()안에 있는것을 복제한다고 생각하면 된다. 그러면 복제된 Human.prototype을 할당하기 때문에 Student.prototype에 메소드를 추가하여도 원본 Human.prototype에는 영향이 없다.
명확한 상속을 위해 constructor도 Student를 할당해준다.
Student.prototype.constructor = Student;
//부모 class
class Human{
constructor(name){
this.name = name;
}
sleep(){
return '자는중...'
}
}
let human1 = new Human('yong') // instance 객체
console.log(human1.sleep()) // 자는중...
//자식 class
class Student extends Human { // extends 상속 키워드
constructor(name,age){
super(name) // super 부모생성자 호출 키워드
this.age = age;
}
learn(){
return '공부중...'
}
}
let student1 = new Student('jun',17)
console.log(student1.sleep()) // 자는중...
console.log(student1.learn()) // 공부중...
console.log(student1.age) // 17
console.log(student1.name) // 'jun'
console.log 값을 직접해보면 ES5와 같은 값이 나온다. 똑같이 상속이 되었다는 의미이다. 위와 같이 ES6의 class,extends,super 키워드를 사용하여 좀 더 깔끔하게 코드를 작성할 수 있다.
new와 this에 대해서 더 공부해보자.