javascript - JS 中的 3 种继承类型 & [.isPrototypeOf()] 结果的差异
问题描述
我相信在Javascript OOP中实现“继承”的方法不止三种。
也许我把这些代码写错了,但是我的代码的结果是用不同的方式操作的。
(环境是 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()
。
推荐阅读
- google-data-studio - 谷歌数据洞察过滤器控制大小写敏感
- python - 当我用 fig.canvas.draw 做 imshow 时,为什么边距这么大?
- monaco-editor - 摩纳哥编辑器:更改默认字形边距悬停工具提示样式
- php - php woocomerce 购物车除法和乘法
- arrays - 用两个条件计算 IFS
- servicestack - 如何测试具有重定向的端点?
- f# - F# 制作不必要的 DateTimeOffset 副本
- kubernetes - 使用 iptables 阻止来自集群外部的所有 Kubernetes 节点端口通信
- shared-libraries - 链接静态库 Vs。Linux 中的共享库
- c# - 如何从属性中获取日期时间,更改 getter 方法中的默认日期类型?