TLDR; 꼭 필요한 것은 아니지만 장기적으로 도움이 될 것이므로 그렇게하는 것이 더 정확합니다.
참고 : 이전 답변이 혼란스럽게 작성되어 신속하게 답변을 놓치면 누락 된 부분이 많으므로 편집 한 내용이 많이 있습니다. 심각한 오류를 지적한 사람들에게 감사합니다.
기본적으로 Javascript에서 하위 클래스를 올바르게 연결합니다. 서브 클래 싱 할 때 prototype
객체 덮어 쓰기를 포함하여 프로토 타입 위임이 올바르게 작동하는지 확인하기 위해 펑키 한 작업을 수행해야 합니다. prototype
객체를 덮어 쓰면에가 포함 constructor
되므로 참조를 수정해야합니다.
ES5의 '클래스'작동 방식을 빠르게 살펴 보겠습니다.
생성자 함수와 프로토 타입이 있다고 가정 해 봅시다.
//Constructor Function
var Person = function(name, age) {
this.name = name;
this.age = age;
}
//Prototype Object - shared between all instances of Person
Person.prototype = {
species: 'human',
}
인스턴스화하기 위해 생성자를 호출하면 다음과 같이 말합니다 Adam
.
// instantiate using the 'new' keyword
var adam = new Person('Adam', 19);
new
'Person'으로 호출 된 키워드는 기본적으로 몇 가지 추가 코드 행으로 Person 생성자를 실행합니다.
function Person (name, age) {
// This additional line is automatically added by the keyword 'new'
// it sets up the relationship between the instance and the prototype object
// So that the instance will delegate to the Prototype object
this = Object.create(Person.prototype);
this.name = name;
this.age = age;
return this;
}
/* So 'adam' will be an object that looks like this:
* {
* name: 'Adam',
* age: 19
* }
*/
우리 경우 console.log(adam.species)
, 조회가 실패 할 adam
경우, 그에게 프로토 타입 체인을 찾아 볼 .prototype
것입니다, Person.prototype
- 그리고 Person.prototype
이.species
조회가에서 성공할 수 있도록 속성을 Person.prototype
. 그런 다음로 기록 'human'
됩니다.
여기에서는 Person.prototype.constructor
을 올바르게 가리 킵니다 Person
.
이제 흥미로운 부분은 소위 '서브 클래 싱'입니다. Student
클래스, 즉 Person
추가 변경 사항 이있는 클래스의 하위 클래스 를 만들려면 Student.prototype.constructor
정확성을 위해 학생을 가리켜 야합니다.
자체적으로는이 작업을 수행하지 않습니다. 서브 클래 싱 할 때 코드는 다음과 같습니다.
var Student = function(name, age, school) {
// Calls the 'super' class, as every student is an instance of a Person
Person.call(this, name, age);
// This is what makes the Student instances different
this.school = school
}
var eve = new Student('Eve', 20, 'UCSF');
console.log(Student.prototype); // this will be an empty object: {}
new Student()
여기서 호출 하면 원하는 모든 속성을 가진 객체가 반환됩니다. 여기서 확인 eve instanceof Person
하면을 반환 false
합니다. 액세스하려고하면 eve.species
반환 undefined
됩니다.
즉, 우리는 그렇게 위임을 연결할 필요가 eve instanceof Person
true를 반환하고 그래서의 경우 Student
제대로 위임에 Student.prototype
다음 Person.prototype
.
그러나 new
키워드로 호출하기 때문에 호출이 추가하는 것을 기억하십니까? 그것은 부를 것이다 Object.create(Student.prototype)
우리는 사이 delegational 관계를 설정하는 방법이다, Student
하고 Student.prototype
. 지금 Student.prototype
은 비어 있습니다. 찾는 지금 .species
의 인스턴스 Student
에 위임하고 있기 때문에 실패 만 Student.prototype
하고 .species
속성에 존재하지 않습니다 Student.prototype
.
에 할당 Student.prototype
하면 Object.create(Person.prototype)
에 Student.prototype
자체를 위임하면 예상대로 Person.prototype
조회 eve.species
가 반환 human
됩니다. 아마도 우리는 그것이 Student.prototype AND Person.prototype에서 상속 받기를 원할 것입니다. 그래서 우리는 그 모든 것을 고쳐야합니다.
/* This sets up the prototypal delegation correctly
*so that if a lookup fails on Student.prototype, it would delegate to Person's .prototype
*This also allows us to add more things to Student.prototype
*that Person.prototype may not have
*So now a failed lookup on an instance of Student
*will first look at Student.prototype,
*and failing that, go to Person.prototype (and failing /that/, where do we think it'll go?)
*/
Student.prototype = Object.create(Person.prototype);
이제 대표단은 작동하지만, 우리는 덮어 쓰기하고 Student.prototype
의와 함께 Person.prototype
. 우리가 호출 Student.prototype.constructor
하면 Person
대신에 가리킬 것입니다 Student
. 이것은 우리가 그것을 해결하기 위해 필요한 이유입니다.
// Now we fix what the .constructor property is pointing to
Student.prototype.constructor = Student
// If we check instanceof here
console.log(eve instanceof Person) // true
ES5에서 우리의 constructor
속성은 '생성자'라는 의도로 작성한 함수를 참조하는 참조입니다. new
키워드가 제공 하는 것 외에도 생성자는 '일반'함수입니다.
ES6에서는 constructor
이제 클래스를 작성하는 방식에 내장되어 있습니다. 클래스를 선언 할 때 메소드로 제공됩니다. 이것은 단순히 구문 설탕이지만 super
기존 클래스를 확장 할 때 액세스 할 수있는 것과 같은 편의를 제공합니다 . 따라서 위 코드를 다음과 같이 작성합니다.
class Person {
// constructor function here
constructor(name, age) {
this.name = name;
this.age = age;
}
// static getter instead of a static property
static get species() {
return 'human';
}
}
class Student extends Person {
constructor(name, age, school) {
// calling the superclass constructor
super(name, age);
this.school = school;
}
}