Я считаю, что существует более трех способов реализации "Наследование" в Javascript OOP.
Возможно, я неправильно написал эти коды, но результат моего кода работает по-разному.
(Env - V8)
/**
* Type 1 : "new" Keyword
*/
//Parent
function newParent(a,b){
this.a = a;
this.b = b;
}
newParent.prototype = {
print : function() {
return this.a + '/' + this.b
}
}
//Child
function newChild(a,b,c) {
newParent.call(this,a,b);
this.c = c;
this.callC = function(){
return this.c;
}
}
newChild.prototype = new newParent();
var O = new newChild(1,2,3);
console.log(O instanceof newChild); //true
console.log(O instanceof newParent); //true
new
ключевое слово в newChild.prototype = new newParent();
,
/**
* Type 2 : "Object.create()"
*/
//Parent
function ocParent(a,b){
this.a = a;
this.b = b;
}
ocParent.prototype = {
print : function() {
return this.a + '/' + this.b
}
}
//Child
function ocChild(a,b,c) {
ocParent.call(this,a,b);
this.c = c;
this.callC = function(){
return this.c;
}
}
ocChild.prototype = Object.create(ocParent.prototype);
ocChild.prototype.constructor = ocChild;
var OO = new ocChild(1,2,3);
console.log(OO instanceof ocChild); //true
console.log(OO instanceof ocParent); //true
Метод Object.create()
в ocChild.prototype = Object.create(ocParent.prototype);
, Кроме того, я подключаю сломанный .constructor
к ocChild
.
И последняя - последняя (?) Форма.
/**
* Type 3 : Class-extends Keyword
*/
class PParent {
constructor(a,b) {
this.a = a;
this.b = b;
}
get print() { //For call this method, Just use '<instance>.print' only.
return this.a + '/' + this.b;
}
}
class CChild extends PParent {
constructor(a,b,c) {
super(a,b);
this.c = c;
}
get callC() { //For call this method, Just use '<instance>.callC' only.
return this.c;
}
}
var OOO = new CChild(1,2,3);
console.log(OOO instanceof CChild); //true
console.log(OOO instanceof PParent); //true
Все <instance_name> instanceof <constructor_name>
возвращает true
. Но результат .isprototypeOf()
O
, OO
, OOO
выглядит следующим образом.
PParent.isPrototypeOf(CChild)
> true
newParent.isPrototypeOf(newChild)
> false
ocParent.isPrototypeOf(ocChild);
> false
Почему эти результаты различны?
Это связано с тем, что ваши первые два метода не инициализируют статическую цепочку прототипов, которую выполняет синтаксис class
:
/**
* Type 1 : "new" Keyword
*/
//Parent
function NewParent(a, b) {
this.a = a;
this.b = b;
}
NewParent.prototype = {
print: function() {
return this.a + '/' + this.b
}
}
//Child
function NewChild(a, b, c) {
NewParent.call(this, a, b);
this.c = c;
this.callC = function() {
return this.c;
}
}
Object.setPrototypeOf(NewChild, NewParent); // this line!
NewChild.prototype = new NewParent();
var O = new NewChild(1, 2, 3);
console.log(O instanceof NewChild); //true
console.log(O instanceof NewParent); //true
console.log(NewParent.isPrototypeOf(NewChild)); //true
/**
* Type 2 : "Object.create()"
*/
//Parent
function OcParent(a,b){
this.a = a;
this.b = b;
}
OcParent.prototype = {
print : function() {
return this.a + '/' + this.b
}
}
//Child
function OcChild(a,b,c) {
OcParent.call(this,a,b);
this.c = c;
this.callC = function(){
return this.c;
}
}
Object.setPrototypeOf(OcChild, Object.create(OcParent)); // this line!
OcChild.prototype = Object.create(OcParent.prototype);
OcChild.prototype.constructor = OcChild;
var OO = new OcChild(1,2,3);
console.log(OO instanceof OcChild); //true
console.log(OO instanceof OcParent); //true
console.log(OcParent.isPrototypeOf(OcChild)); //true
Я не утверждаю, что любой из них идентичен тому, как работает синтаксис class
, только что они теперь инициализируют статическую цепочку прототипов способом, который подтвержден с isPrototypeOf()
.