在JavaScript中实现继承主要实现如下两方面的属性和方法的继承,这两方面相互互补,既有共享的属性和方法,又有特有的属性和方法。javascript
ES5的继承方式有多种:主要有原型链继承、借用构造函数、组合式继承、寄生式继承和寄生组合式继承。寄生组合式继承集
组合式继承和寄生式继承的优势于一身,是ES5中,基于类型继承的最有效方式。
接下来基于寄生组合式继承对ES5实现继承的方面进行解释。java
//父类 function SuperType(name){ //父类实例属性 this.name = name; this.colors = ["red", "blue", "green"]; } //父类原型方法 SuperType.prototype.sayName = function(){ alert(this.name); }; //子类 function SubType(name, age){ SuperType.call(this, name);//1.借用构造函数:继承父类的实例属性; this.age = age; } //2.寄生式继承:将父类原型的副本强制赋值给子类原型,实现继承父类的原型方法。 inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function(){ alert(this.age); }; function inheritPrototype(subType, superType){ var prototype = object(superType.prototype); //建立父类原型的副本 prototype.constructor = subType; //将该副本的constructor属性指向子类 subType.prototype = prototype; //将子类的原型属性指向副本 }
以上示例就是ES5中寄生组合式继承
的一个例子,如何实现子类继承父类?函数
SuperType.call(this, name);
:当new SubType()
建立子类实例时,首先调用父类构造函数,实现了子类实例继承父类的实例属性和方法;inheritPrototype(SubType, SuperType);
:将父类原型副本强制替换成子类原型(1.副本constructor指向子类;2.子类prototype指向副本),使得子类原型包含父类原型中的全部属性和方法,实现了原型属性和方法的继承。ES5中经过函数建立类型并基于原型实现继承的方式与其余面向对象的语言相比确实比较另类,没有那么简单明了;ES6就提供了更加接近传统语言的写法,引入了类的概念。this
class
关键字定义类class super{ constructor(name,color){ this.name=name; this.color=["red","blue","green"]; } sayName(){ alert(this.name); } }
1. constructor为构造函数,若是非显示建立构造函数,定义类时也会自动建立构造函数; 2. 经过`this`定义的属性和方法属于实例属性和方法;不然都是定义在原型上的属性和方法; 3. class类中定义的方法`constructor、sayName`都属于原型方法。
extends
实现类的继承class Person{ constructor(name,color){ this.name=name; this.color=["red","blue","green"]; } sayName(){ alert(this.name); } } class Student extends Person(){ constructor(name,color,score){ super(name,color);//调用父类构造函数,this指向子类 this.score=score; } showScore(){ alert(this.score); } } let stu1=new Student("xuxu",["white","black","pink"],90); stu1.sayName();//"xuxu" stu1.showScore();//90
1. 子类构造函数中调用父类构造函数,实现了子类继承父类的实例属性和方法; 2. 经过extends,子类原型继承父类原型上的属性和方法: - Student.__proto__=Person;//做为对象,子类原型等于父类(构造函数的继承) - Student.prototype.__proto__=Person.prototype;//做为构造函数,子类原型对象是父类原型对象的实例。 3. 子类静态方法继承父类静态方法 - 静态方法的定义:关键字static; - 调用方法:类名调用(而不是实例调用); - 普通方法中,super做对象表示父类原型(用来调用父类原型方法); 静态方法中super做对象表示父类(用来调用父类静态方法)。 - 普通方法中this指向实例对象;静态方法中hits指向当前子类。
对象(实例和原型对象)有__proto__属性,构造函数有prototype属性,原型对象有constructor属性。
假设class B extends A
,实例对象分别是insB、insA
:prototype
ES5中:code
ES6中:对象