js面向对象的继承
一、js继承的定义
继承是面向对象语言中最为人津津乐道的概念。许多面向对象的语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。由于函数没有签名,无法实现接口继承,所以只支持实现继承,而实现继承主要依靠原型链来实现的。
二、以下是实现继承的五种方式
-
原型链:原型链实现继承基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。说到原型链,我们不得不说构造函数,首先创建一个构造函数,通过new返回构造函数的实例,每个构造函数都有原型对象,原型对象的constructor属性指向构造函数,而实例包含一个内部指针隐式原型_proto_也指向原型对象,而如果我们将此构造函数的原型对象作为另一个构造函数返回的实例,就可以继承到另一个构造函数的属性和方法,以及它原型对象上的属性和方法,如果再将次构造函数再次作为有一个构造函数的实例,就又可以继承到另一个构造函数自身以及原型上的属性和方法,如此层层查找,最终指向object,就是原型链继承。
缺点:原型链继承会将父类的私有属性、方法和共有属性和方法都继承为自己的公有方法,并且子类可以重写父类的方法,使得父类的其他实例也会改变。 -
借用构造函数继承,如下实例,通过函数的call改变this的指向Dog作用域中,实现继承。
function Animal(){ this.name="猪"; this.age=18; } Animal.prototype.love="吃"; function Dog(){ Animal.call(this); } var dog1=new Dog(); console.log(dog1.love)//undefined
缺点:只能继承到父类的私有属性,父类原型对象的属性继承不到,导致属性和方法无法 复用。
-
组合继承
就是将原型链和借用构造函数组合使用,如下function Animal(){ this.name="猪"; this.age=18; } Animal.prototype.love="吃"; Dog.prototype=new Animal(); Dog.prototype.constructor=Dog;//为了保证原型链的机制,指向自己。 function Dog(){ Animal.call(this); } var dog1=new Dog(); console.log(dog1.love)//吃
缺点:父类的构造函数执行了两边。增加了内存消耗。
-
寄身式继承
通过object.creat()方法,创建一个空对象,然后使得空对象指向父类的原型,不需要创建构造函数,实现原想对象的继承,如下所示:function Animal(){ this.name="猪"; this.age=18; } Animal.prototype.love="吃"; Dog.prototype=Object.create(Animal.prototype); Dog.prototype.constructor=Dog;//为了保证原型链的机制,指向自己。 function Dog(){ } var dog1=new Dog(); console.log(dog1.love)//吃
缺点:只能继承共有属性和方法,不能继承私有的属性和方法,由于object.create()兼容性的问题,可以自己手动写一个,例如:
function create(Animal){ function Fn(){ } Fn.prototype=Animal return new Fn(); }
-
寄身组合继承,最常用的一种方式。
function Animal(){ this.name="猪"; this.age=18; } Animal.prototype.love="吃"; Dog.prototype=Object.create(Animal.prototype); Dog.prototype.constructor=Dog;//为了保证原型链的机制,指向自己。 function Dog(){ Animal.call(this); } var dog1=new Dog(); console.log(dog1.love)//吃
如有错误,欢迎指正!