JavaScript 클래스 및 상속
우선은 안녕.
이걸로 손잡는 사람은 없다고 생각합니다.
하지만, 구체적으로 Base라는 클래스를 Derived라는 클래스가 상속해, 그 객체를 new로 만들었다고 하는 경우에, 프로토타입 체인이 어떻게 구축되는지를 분명히 설명할 수 있는 사람은 적은 것 같은 생각이 듭니다 .
문장으로 어딘지 모르게 설명해도 반드시 이해하기 어려워지기 때문에, 결론으로부터 그림으로 그려 버리면 이렇게 되어 있는 것입니다.
생성자와 클래스 객체는 별개로, constructor 과 prototype 라고 하는 필드로 상호 참조하고 있다고 하는 점이 초보자에게는 이해하기 어렵다고 생각합니다.
__proto__
라는 필드는 내부 프로토 타입 체인을 구현하기위한 참조이며 코드에서 직접 액세스해서는 안됩니다.이러한 상속 관계가 구축되고 있는 것은, 아래와 같은 코드로 확인할 수 있습니다.
class Base{
}
class Derived extends Base{
}
const base = new Base()
const derived = new Derived()
console.log(derived.__proto__.__proto__ === base.__proto__)
console.log(base.constructor === Base)
console.log(derived.constructor === Derived)
console.log(Derived.prototype.__proto__ === Base.prototype)
console.log(Base.prototype.__proto__ === Object.prototype)
console.log(Derived.__proto__ === Base)
console.log(Base.__proto__ === Function.__proto__)
console.log(function(){}.__proto__ === Function.prototype)
console.log(function(){} instanceof Function)
ES5 이전
ES5 이전에는 Java 스타일의 클래스 구문이 없었기 때문에 다음과 같이 작성하는 방법이 좋았습니다.
Derived.prototype = new Base()
그러나, 실은 이것에서는 전술의 상속 관계를 구축하기에는 불충분하고, 프로토타입으로부터 constructor 에의
constructor
필드에 의한 참조가 구축되지 않습니다. 상호 참조해야 할 곳이 한 참조입니다.이를 올바르게 구현하려면 이전 브라우저와의 호환성을 고려하여 다음과 같은 함수를 정의해야 했습니다.
/// Custom inheritance function that prevents the super class's constructor
/// from being called on inehritance.
/// Also assigns constructor property of the subclass properly.
function inherit(subclass,base){
// If the browser or ECMAScript supports Object.create, use it
// (but don't forget to redirect constructor pointer to subclass)
if(Object.create){
subclass.prototype = Object.create(base.prototype);
}
else{
var sub = function(){};
sub.prototype = base.prototype;
subclass.prototype = new sub;
}
subclass.prototype.constructor = subclass;
}
사용법은 이런 느낌입니다.
function Base(){
}
function Derived(){
Base.call(this)
}
inherit(Derived, Base)
글쎄, 귀찮다.
ES6에서 class 구문이 도입된 것은 좋은 일입니다만, 왜 처음부터 준비해 주지 않았다고 말하고 싶어집니다. 이것은 함수형 의 상속과 프로토타입 베이스의 상속을 취향에 따라 선택할 수 있도록 하기 위해서는 아닐까 나는 생각하고 있습니다.
왜 이렇게 되었습니까?
생성자와 프로토 타입 객체가 다른 이유는 무엇입니까? 생각해 보면 알 수 있습니다만, 생성자는 어디까지나 함수이므로, 프로토타입에 Function 를 가져, call
나 apply
라고 하는 메소드를 계승하고 있습니다. 새롭게 정의하는 클래스는, 물론 함수의 동료라고는 할 수 없기 때문에, 프로토타입 체인에 Function 를 포함하고 싶지는 않네요.
객체 모델을 생각하면 이러한 사양이 되는 것은 납득할 수 없어도 되지 않습니다만, C++ 나 Java 의 객체 지향에 익숙한 사람에게는 익숙해지기가 어려운 것은 아닐까요. 음, Brendan Eich는 반의식적으로 이렇게 했다 1 같습니다만.
자바스크립트 20years 라는 논문에서 거기에 대한 자세한 내용을 되돌아보고 있습니다. 자바스크립트는 10일 만에 첫 번째 버전이 작성되었다는 전설에 대해서도 본인이 실제를 밝히고 있는 흥미로운 독서입니다. htps // dl. 아 cm. rg/도이/10.1145/3386327 ↩
Reference
이 문제에 관하여(JavaScript 클래스 및 상속), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/msakuta/items/b80675caf7be4208f9c9
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(JavaScript 클래스 및 상속), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/msakuta/items/b80675caf7be4208f9c9텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)