JS对面向对象编程继承的详细解释
原型链(原型链接):使用原型继承属性和方法。检查构造函数(构造函数)、原型对象(原型)和实例(实例)之间的关系。每个构造函数都有一个原型属性,它指向一个原型对象。原型对象也有构造函数属性指向该函数;和实例也有一个内部的指针(__proto__)指该原型对象。如果这个原型对象是另一个对象的一个实例吗因此,原型对象包含指向另一个类型的指针。相应地,另一个原型包含指向另一个构造函数的指针。
js的继承者非常简单,就是处理类原型父类A(对象实例化)。
复制代码代码如下所示:
函数的SuperType(){
this.property =真;
}
supertype.prototype.getsupervalue =函数(){
返回this.property;
};
函数SubType(){
this.subproperty = false;
}
/ /继承父类型
subtype.prototype =新类型();
subtype.prototype.getsubvalue =函数(){
返回this.subproperty;
};
var实例=新的子类型();
警报(instance.getsupervalue()); / /真的
最终的结果是,subtype.prototype实例指向对象的__proto__,而subtype.prototype对象指向supertype.prototype object.getsupervalue的__proto__属性()是一种方法,所以它仍然存在于原型,财产是一个实例的属性,所以现在在subtype.prototype instance.instance.constructor现在指的是父类,这是因为SubType.prototype指出supertype.prototype,而父类型。原型的构造函数属性指向父类型的功能,所以instance.constructor点类型。
默认情况下,所有引用类型继承的对象。这是因为所有函数的原型对象,默认的是对象的一个实例,所以内部的原型(__proto__)指向object.prototype。
原型和实例之间的关系:2种方法可以用来确定原型和实例之间的关系。
- instancef算子:使用此运算符测试实例中发生的构造函数和原型链,他们都回到真实
复制代码代码如下所示:
警报(实例实例对象); / /真的
警报(实例实例类型); / /真的
警报(实例是亚型); / /真的
- isprototypeof()方法:只要是在原型链中的一个原型,它可以说是来自原型链实例原型。
复制代码代码如下所示:
警报(Object.prototype.isPrototypeOf(实例)); / /真的
警报(supertype.prototype.isprototypeof(实例)); / /真的
警报(subtype.prototype.isprototypeof(实例)); / /真的
注意到子类的方法:有时我们添加方法的子类,或者一些方法,重写父类。这时候需要注意的是,这些方法必须重新定义继承。在下面的例子中,后继承父类型的亚型,我们添加一个新的方法getsubvalue()它,并改写了getsupervalue()方法。对于后者,只有一个实例的类型将使用重写的方法,和父类型的实例将仍然使用原来的getsupervalue()方法。
复制代码代码如下所示:
函数的SuperType(){
this.property =真;
}
supertype.prototype.getsupervalue =函数(){
返回this.property;
};
函数SubType(){
T his.subproperty = false;
}
/ /继承父类型
subtype.prototype =新类型();
/新方法
subtype.prototype.getsubvalue =函数(){
返回this.subproperty;
};
覆盖现有方法
subtype.prototype.getsupervalue =函数(){
返回false;
};
var实例=新的子类型();
警报(instance.getsupervalue()); / /假
要注意的另一件事是,当原型链继承,原型法不能使用对象字面量创建的,因为它将原型链。例如,下面的代码是用来在继承父类型的亚型。它使用对象的字体将方法添加到原型中,但它将重写子类型原型。改写的subtype.prototype包含对象的一个实例,这也切断了与父类的关系。
复制代码代码如下所示:
函数的SuperType(){
this.property =真;
}
supertype.prototype.getsupervalue =函数(){
返回this.property;
};
函数SubType(){
this.subproperty = false;
}
/ /继承父类型
subtype.prototype =新类型();
/ /尝试添加新的方法使以前的线-这
subtype.prototype = { {
GetSubValue:函数(){
返回this.subproperty;
},
someothermethod:函数(){
返回false;
}
};
var实例=新的子类型();
警报(instance.getsupervalue()); / /错误!
该原型链的问题:作为原型,当引用类型的值是用于原型链将毫无疑问。回顾以前的内容,一个原型属性包含一个参考值的所有实例共享,这就是为什么我们定义的构造函数,而不是原型的引用类型的值当原型链实现继承,原型将成为另一个实例。因此,原始实例属性也是成功的。
复制代码代码如下所示:
函数的SuperType(){
this.colors = {红,蓝,绿};
}
函数SubType(){
}
/ /继承父类型
subtype.prototype =新类型();
请为新的亚型(VAR);
instance1.colors.push(黑色);
(请警惕。颜色); / /红色,蓝色,绿色,黑色
无功instance2 =新的亚型();
警报(instance2。颜色); / /红色,蓝色,绿色,黑色
在父类的构造函数,我们定义了一系列的色彩,每一种都有其自己的颜色数组的类型。但当亚型与原型链继承父类,subtype.prototype成为超类的一个实例,所以它有它自己的颜色属性,这是subtype.prototype.colors属性。所以,当亚型实例被创建,所有实例共享此属性。如上面的代码所示。
第二个问题是,当一个子类的实例被创建时,参数不能被传递给基类构造函数。事实上,应该说,是没有办法通过父类的构造函数的参数而不影响所有对象实例。因为这些问题,我们不能单独使用原型链。
--------------------------------------------------------------------------------
使用构造函数(构造函数偷):
为了解决这个问题,开发商发明了一种叫做借用构造函数。该技术的思想是在亚超类型调用构造函数构造函数。(一个函数,只有一个对象执行的代码在一个特定的环境)我们可以通过使用应用程序()或调用()方法在新创建的对象上执行构造函数。
复制代码代码如下所示:
函数的SuperType(){
this.colors = {红,蓝,绿};
}
函数SubType(){
/ /继承父类型
supertype.call(本);
}
请为新的亚型(VAR);
instance1.colors.push(黑色);
(请警惕。颜色); / /红色,蓝色,绿色,黑色
无功instance2 =新的亚型();
警报(instance2。颜色); / /红色,蓝色,绿色
在SubType,我们用电话()调用父类的构造函数的方法,这实际上是执行所有对象的初始化代码中定义的类型()的新类型对象的功能。结果是,每个亚型实例都有一份自己的颜色属性。
传递参数:使用借用构造函数方法的最大好处之一是,我们可以从类构造函数将参数传递给父类的构造函数。
复制代码代码如下所示:
函数的SuperType(化名){
this.name =名称;
}
函数SubType(){
/ /继承父类型传递参数
supertype.call(本、尼古拉斯);
实例属性
this.age = 29;
}
var实例=新的子类型();
警报(实例名);尼古拉斯;
警报(实例.年龄);29
新的超类构造函数添加一个参数的名称,我们通过参数尼古拉斯的类型,调用超类型。为了不被父类构造函数改写亚型亚型,你可以重新定义子类的构造函数调用父类的属性后。
借用构造函数的问题:方法是在构造函数不能定义可重用。在超类中定义的方法是不可见的子类型,所有类型只能使用构造函数模式。
--------------------------------------------------------------------------------
组合继承:
继承的模式,结合原型链优势和借款人的构造函数。原型链继承使用原型属性和方法,并使用借款构造函数继承实例属性,如下面的示例中,我们使用电话()方法调用超类构造函数(亚型的每个实例都有名称和颜色属性,他们的年龄和类型属性);然后父类型实例分配给亚型原型,继承父类型sayname()方法(每个实例共享此方法)。
复制代码代码如下所示:
函数的SuperType(化名){
this.name =名称;
this.colors = {红
}
supertype.prototype.sayname =函数(){
警报(这个名字);
};
函数SubType(名称,年龄){
继承属性
supertype.call(这名字);
this.age =年龄;
}
继承方法
subtype.prototype =新类型();
subtype.prototype.sayage =函数(){
警戒(这个年龄);
};
VaR请=新的亚型(尼古拉斯
instance1.colors.push(黑);
(请警惕。颜色); / /红色,蓝色,绿色,黑色的
(请。sayname); / /尼古拉斯;
instance1.sayage(); / / 29
无功instance2 =新的亚型(格雷戈
警报(instance2。颜色); / /红、蓝、绿
(instance2。sayname); / /格雷戈;
instance2.sayage(); / / 27
原型继承(原型继承):
复制代码代码如下所示:
函数对象(O){
函数(f){ }
f.prototype = O;
返回新的f();
}
--------------------------------------------------------------------------------
寄生继承(寄生遗传):
缺点和构造函数