JS是一门弱类型动态语言,封装和继承是他的两大特性
1原型链继承
将父类的实例作为子类的原型
1.代码实现
定义父类:
// 定义一个动物类 function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); } } // 原型方法 Animal.prototype.eat = function(food) { console.log(this.name + '正在吃:' + food); };
子类:
function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = 'cat'; // Test Code var cat = new Cat(); console.log(cat.name);//cat console.log(cat.eat('fish'));//cat正在吃:fish undefined console.log(cat.sleep());//cat正在睡觉! undefined console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true
2.优缺点
简单易于实现,但是要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,无法实现多继承
2 构造继承
实质是利用call来改变Cat中的this指向
1.代码实现
子类:
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; }
2.优缺点
可以实现多继承,不能继承原型属性/方法
3 实例继承
为父类实例添加新特性,作为子类实例返回
1.代码实现
子类
function Cat(name){ var instance = new Animal(); instance.name = name || 'Tom'; return instance; }
2.优缺点
不限制调用方式,但不能实现多继承
4 拷贝继承
将父类的属性和方法拷贝一份到子类中
1.子类:
function Cat(name){ var animal = new Animal(); for(var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.name = name || 'Tom'; }
2.优缺点
支持多继承,但是效率低占用内存
5 组合继承
通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
1.子类:
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } Cat.prototype = new Animal(); Cat.prototype.constructor = Cat;
6 寄生组合继承
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } (function(){ // 创建一个没有实例方法的类 var Super = function(){}; Super.prototype = Animal.prototype; //将实例作为子类的原型 Cat.prototype = new Super(); })();
7 ES6的extends继承
ES6 的继承机制是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this,链接描述
//父类 class Person { //constructor是构造方法 constructor(skin, language) { this.skin = skin; this.language = language; } say() { console.log('我是父类') } } //子类 class Chinese extends Person { constructor(skin, language, positon) { //console.log(this);//报错 super(skin, language); //super();相当于父类的构造函数 //console.log(this);调用super后得到了this,不报错,this指向子类,相当于调用了父类.prototype.constructor.call(this) this.positon = positon; } aboutMe() { console.log(`${this.skin} ${this.language} ${this.positon}`); } } //调用只能通过new的方法得到实例,再调用里面的方法 let obj = new Chinese('红色', '中文', '香港'); obj.aboutMe(); obj.say();
更多详情请戳:JS继承的实现方式