Javascript中继承方式的详细解释
js中常用的以下两种继承方式:
原型链继承(对象之间的继承)
类继承(构造函数间的继承)
因为JS不是一个真正的面向对象的语言,如java,js是基于对象的,它没有阶级观念,实现继承,你可以使用JS的原型样机的机构或申请和调用方法来实现它
在面向对象的语言中,我们使用类来创建一个自定义对象,但是js中的所有东西都是对象,您用什么方式创建自定义对象这需要在js的原型中使用:
我们可以简单的把原型为模板,自定义新创建的对象的模板(原型)一份(但不是复制链接,但这个链接是不可见的,内部对象新实例化的一个看不见的__proto__指针,指向原型对象)。
js可以通过构造函数和原型来模拟类的功能,另外,js类型继承的实现依赖于原型链。
原型继承与类继承
类继承是一个父类构造函数构造函数调用在亚型。
严格的类继承不是很常见,它通常用于组合:
复制代码代码如下所示:
函数超级(){
这个颜色= 红色
}
函数子(){
super.call(本);
}
原型继承是使用现有对象创建新对象,将子类的原型指向父类,这相当于将父类添加到原型链中。
原型链继承
为了允许子类继承父类的属性(也包括方法),首先需要定义一个构造函数。然后,父类的新实例被分配给构造函数的原型:
复制代码代码如下所示:
函数父(){
this.name =吧;
}
函数子(){
this.age = 12;
}
child.prototype =新的父(); / /孩子继承父母通过原型形式链
var测试=新子();
警报(测试,年龄);
警报(测试名称);获取继承的属性
继续原型链继承
函数兄弟()兄弟结构
this.weight = 60;
}
brother.prototype =新的(孩子); / /继续原型继承链
var兄弟=新兄弟();
警报(兄弟姓名);父/子的继承者,POP迈克
警报(兄弟,年龄);12
上面的原型链继承仍然缺失,也就是说,对象和所有构造函数都继承自对象,继承对象是自动的,不需要我们自己的手工继承,那么它们的从属关系是什么呢
确定原型和实例之间的关系
有两种方法来确定原型和实例的关系。操作实例和isprototypeof()方法:
复制代码代码如下所示:
警报(哥哥是对象) / /真的
警报(测试是兄弟); / /假,考试是哥哥的超类
警报(哥哥是孩子); / /真的
警报(哥哥是父母); / /真的
只要出现在原型链的原型可以说是来自原型链的实例的原型,该isprototypeof()方法也会返回真
在JS,继承的函数称为超类(父类,基类也行),和继承的函数被称为亚类(子类、派生类)。原型继承的使用主要是由两个问题:
首先,文字改写的原型将中断的关系,使用引用类型的原型,和亚型不能通过参数的类型。
伪类的解决问题,参考共享和类型不能通过,我们可以利用借来的施工技术
借用构造函数(类继承)
复制代码代码如下所示:
函数父(年龄){
this.name = {吧,杰克,'smith};
this.age =年龄;
}
函数子(年龄){
parent.call(这个年龄);
}
var测试=新子(21);
警报(测试年龄);21
警报(测试名称);杰克,史米斯
Test.name.push(比尔);
警报(测试名称);/迈克/迈克,杰克,史米斯,比尔
虽然使用构造函数来解决两个问题,但没有原型,不可能重用。因此,我们需要原型链+借用构造函数的模式。这种模式称为组合继承。
组合继承
复制代码代码如下所示:
函数父(年龄){
this.name = {吧,杰克,'smith};
this.age =年龄;
}
(parent.prototype.run =功能){
返回this.name +都+ this.age;
};
函数子(年龄){
parent.call(这个年龄); / /对象类型参数的超级假。
}
child.prototype =新(母); / /原型继承链
var测试=新的子(21);写入新的父(21)行
警报(test.run()); / / Mike,杰克,史米斯both21
组合继承是一种常用的继承方法。其思想是利用原型链实现原型属性和方法的继承,通过借用构造函数实现对实例属性的继承,通过原型定义方法实现函数重用,每个实例都有自己的属性。
调用():调用对象用另一个对象替换当前对象的一种方法。
复制代码代码如下所示:
电话(thisobj { { { {,arg1,arg2,{,argn }}}}}。)
原型继承
此继承基于原型创建基于对象的新对象,也称为原型继承而不创建自定义类型。
复制代码代码如下所示:
函数对象(O){
函数(f){ }
f.prototype = O;
返回新的f();
}
变量框{ {
名称:'trigkit4,
Arr:{哥','妹妹','baba }
};
VaR B1 = obj(箱);
警报(B1。名称); / / trigkit4
b1.name =吧;
警报(B1名称);
警报(B1,ARR); / /哥哥,姐姐,Baba
b1.arr.push('parents);
警报(B1,ARR); / /兄弟,姐妹,父母巴巴,
VaR B2 = obj(箱);
警报(B2。名称); / / trigkit4
警报(B2,ARR); / /兄弟,姐妹,父母巴巴,
原型继承首先创建内部对象临时构造函数()函数,然后将传入的对象的构造函数的原型,并返回该临时类型的新实例。
寄生继承
这种继承是原型+工厂模型和封装创建过程的目的的结合。
复制代码代码如下所示:
函数创建(o){
var = obj(O);
f.run =函数(){
返回this.arr; / /相同,将分享参考
};
返回F;
}
组合遗传的一个小问题
组合继承是JS最常用的继承模式,但在使用过程中将会调用两种类型的组合继承,一种是创建子类型,另一种是在子类型构造函数内。
复制代码代码如下所示:
函数父(名称){
this.name =名称;
this.arr = { '兄弟','姐姐','父母' };
}
(parent.prototype.run =功能){
返回this.name;
};
函数子(名称,年龄){
parent.call(这个年龄); / /二电话
this.age =年龄;
}
child.prototype =新(母); / /第一个电话
上面的代码是以前的继承组合,然后是继承的寄生组合,解决了两个调用的问题。
寄生组合继承
复制代码代码如下所示:
函数对象(O){
函数(f){ }
f.prototype = O;
返回新的f();
}
函数创建(父,测试){
var = obj(母。原型); / /创建对象
f.constructor =试验; / /目标增强
}
函数父(名称){
this.name =名称;
this.arr = {哥','妹妹','parents };
}
(parent.prototype.run =功能){
返回this.name;
};
函数子(名称,年龄){
parent.call(这名字);
this.age =年龄;
}
InheritPrototype(父母,子女); / /实现继承通过这里
VaR测试=新的儿童('trigkit4 ',21);
Test.arr.push('nephew);
警报(测试。ARR); / /
警报((测试运行));仅共享方法
VaR test2 =新的儿童(杰克',22);
警报(test2。ARR); / /参考解决问题
调用和应用
全局函数应用和调用可以用来改变函数中的这个方向,如下所示:
复制代码代码如下所示:
定义一个全局函数
函数(){
(这console.log。水果);
}
定义一个全局变量
苹果;
自定义对象
var
水果:橙
};
(与窗口等效);
foo.apply(窗口); / / 苹果
在这个时候,这个包
foo.apply(包); / /橙