继承
前言
原型是’Javascript’中的继承的基础,JavaScript的继承就是基于原型的继承。
ES6的继承
class Box{
constructor(){
}
play(){
}
}
class Ball extends Box{
constructor(){
super();
}
}
ES5的继承
如果把父类的实例化对象放在子类的原型下就叫继承
eg:
var obj={...};
var o=Object.create(obj);
console.log(o);
o的原型链,就是Obj的原型
var b=new Box();
var o=Object.create(b);
实例化对象的原型链,就是类的原型
即o的原型链,就是Box的原型
如果是基类,可以直接这样写,但是后面还必须重新定义constructor为当前类的构造函数
如果不是基类,就不能直接使用prototype重设置对象
function Box(_r){
this.r=_r;
console.log("aa");
}
Box.a=3;
Box.run=function(){
console.log(Box.a);
}
Box.prototype.b=10;
Box.prototype.play=function(){
console.log(this.b);
}
以上是ES5的面向对象的写法。
那一下这种写法可以吗?
答:不完全正确!
Box.prototype={
b:10,
play:function(){
}
}
ES5的类中,只要创建这个类以后,就会自动有一个原型,自动具备。
// 如果是基类,可以直接这样写,但是后面还必须重新定义constructor为当前类的构造函数
// 如果不是基类,就不能直接使用prototype重设置对象
Object.defineProperty(Box.prototype,"constructor",{
value:Box
})
补上constructor即可
如果把父类的实例化对象放在子类的原型下就叫继承
组合式继承(对象冒充)
有问题的,错误的, 超类的构造函数被执行两遍,这种继承适合于超类的构造函数中没有任何语句
function a(){
this.name = 'a';
}
a是超类
a.prototype.play =function(){
console.log(this.name);
}
function b(){
this.name = 'b';
a.prototype.play.call(this)//冒充
}
b是子类,a的构造函数被执行了两两遍。
b()
原型继承
这种方式虽然不执行两遍超类的构造函数,但是一边都没有执行,只完成了原型的继承。
function F(){
}
F.prototype=Box.prototype;
F继承了Box的所有属性,除了构造函数以外,都是被继承的,都和Box一样。
function Ball(){
}
Ball.prototype=new F();
这里Ball的构造函数是自身的构造函数,直接继承的了F。
var b=new Ball();
console.log(b);
Object.creat()的继承
但是这种继承的写法只能用于IE9版本以上的浏览器。(Object.creat()要求)
function Ball(_r){
Box.call(this,_r)
}
Ball.prototype = Object.create(Box.prototype);
var b = new Ball;
寄生式继承
function extend(subClass,supClass){
function F(){}
F.prototype=supClass.prototype;
// subClass.prototype=new F();
// Object.assign(subClass.prototype,new F());
var o=subClass.prototype;
subClass.prototype=new F();
// 复制原来的原型下的所有内容
if(Object.assign){
// 如果Object.assign可以使用时
Object.assign(subClass.prototype,o);
}else{
// Object.getOwnPropertyNames可以使用时
if(Object.getOwnPropertyNames){
var names=Object.getOwnPropertyNames(o);
for(var i=0;i<names.length;i++){
Object.defineProperty(subClass.prototype,names[i],Object.getOwnPropertyDescriptor(names[i]));
}
}else{
for(var prop in o){
subClass.prototype[prop]=o[prop]
}
}
}
subClass.prototype.constructor=subClass;
subClass.prototype.superClass=supClass
if(supClass.prototype.constructor===Object){
supClass.prototype.constructor=supClass;
}
}