面向对象继承的几种方式
类式继承
一般类式继承是继承私有属性,调用父类通过call改变子类this指向
function Person1(name,age){ this.name = name; this.age = age; } function Coder1(name,age,job){ //调用父类Person,通过call改变this Person1.call(this,name,age); this.job = job; console.log(this); } let p1 = new Person1('阿凡达',2009); let c1 = new Coder1('卡梅隆',56,'导演')
拷贝继承
把一个对象的属性和方法直接复制到另一个对象中
使用for in 遍历父类身上的方法,只要是自身的就赋值给子类的原型
子类通过for in继承父类的方法(把父类的东西都继承过来),子类新加的方法父类不会有
function Person2(name,age){ this.name = name; this.age = age; } Person2.prototype.say = function(){ console.log('我说'+this.name); } Person2.prototype.run = function(){ console.log('我会跑'); } function Coder2(name,age,job){ Person2.call(this,name,age); this.job = job; } //Person2.prototype == Coder2.prototpe;//此时已经赋值了 for(let attr in Person2.prototype){ //如果父级有这些方法,就让父级复制一份给子类 if(Person2.prototype.hasOwnProperty(attr)){ Coder2.prototype[attr] == Person2.prototype[attr]; } } //这样继承下来不是继承他的地址,改变一些方法也不影响Person Coder2.prototype.runing = function(){ console.log('飞快的火车'); } let p2 = new Person2('Tom',20); let c2 = new Coder2('Jack',22,'reporter'); c2.runing(); console.log(Coder2.prototype);
使用Object.assign()拷贝
function Person(name,age){ this.name = name; this.age = age; } Person.prototype.say = function(){ console.log('我的名字'+this.name); } Person.prototype.run = function(){ console.log('我会跑'); } function Coder(name,age,job){ Person.call(this,name,age); this.job = job; } //Coder.prototype = Object.assign({},Person.prototype);//浅拷贝 Object.assign(Coder.prototype,Person.prototype); Coder.prototype.say = function(){ console.log('我会唱歌'); } let c = new Coder('paul',26,'主席'); let p = new Person('rondo',26) c.run(); p.say();
原型继承
原型继承主要是继承父类身上的属性和方法
1)创建一个空的构造函数
2)把空构造函数的原型等于父级的原型
3)把子类的原型等于new空函数
这样就达到了继承属性的目的
function Pn(name){ this.name = name; } Pn.prototype.say = function(){ console.log('交流'); } Pn.prototype.run = function(){ console.log('跑步'); } function Cn(name){ Pc.call(this,name); } function Temp(){} Temp.prototype = Pn.prototype; Cn.prototype = new Temp;
寄生组合式继承
子类私有继承父类私有,子类公有继承父类公有
属性继承:通过call继承的方法,将父类中的私有属性赋值一份到子类的私有属性中
方法继承:通过Object.create将父类的原型当作参数传入,返回值是一个空对象
将其赋值给子类的原型,这样子类的原型就通过_proto_原型链找到父类的原型
function Pn(name){ this.name = name; } Pn.prototype.say = function(){ console.log(this.name); } function Cn(name){ Pn.call(this,name); } Cn.prototype = Object.create(Pn.prototype);
ES6继承
es6给我们提供了语法糖,可以用class创建类
通过extends继承父类属性,如果有添加constructor函数的话就必须使用super,否则会报错
super属于call继承,可以通过super给父类传参,super上面有死区,上方输入this也会报错
class Person{ constructor(name,age){ this.name = name; this.age = age; } //静态方法 static say(){ console.log(1); } //动态方法 say(){ console.log(2); } } class Coder extends Person{ constructor(job,...arg){ super(...arg); this.job = job; } coding(){ console.log(this.job); } } let p = new Person('Tom',22); let c = new Coder('Jack',18,'student'); Person.say();//调用Person静态方法 p.say();//调用Person动态方法 c.say();//继承了父类的方法 c.coding();//student 调用Coder动态方法