类的声明方式
/**
* 类的声明
*/
function Animal () {
this.name = 'name';
}
/**
* ES6中的class的声明
*/
class Animal2 {
constructor () {
this.name = name;
}
}
/**
* 实例化
*/
console.log(new Animal(),new Animal2());
继承方式
/**
* 借助构造函数实现继承
*/
function Parent1 () {
this.name = 'parent1';
}
function Child1() {
Parent1.call(this); //apply
this.type = 'child';
}
通过call或者apply来改变函数运行的上下文,将父级构造函数放在子类里面执行并改变this指向,从而导致父类执行它的属性都会挂载到子类的类实例上去。
缺点:父类构造函数是有自己的原型链的,按照构造函数实现继承,Parent1原型链上的属性没有被Child1继承。
/**
* 借助原型链实现继承
*/
function Parent2 () {
this.name = 'parent2';
}
function Child2 () {
this.type = 'child2';
}
Child2.prototype = new Parent2();
缺点:修改一个实例对象的属性,另一个实例对象会受到影响。这个缺点的原因是原型对象它们是共用的。
/**
* 组合方式
*/
function Parent3 (){
this.name = 'parent3';
this.play = [1,2,3];
}
function Child3 () {
Parent3.call(this); //第一次
this.type = 'child3';
}
// 第二次
Child3.prototype = new Parent3();
var s3 = new Child3();
var s4 = new Child3();
缺点:父类的构造函数执行了两次,然而这两次是没有必要的。
/**
* 组合继承的优化方式
*/
function Parent4 (){
this.name = 'parent4';
this.play = [1,2,3];
}
function Child4 () {
Parent4.call(this); //第一次
this.type = 'child3';
}
// 第二次
Child4.prototype = Parent4.prototype;
var s5 = new Child4();
var s6 = new Child4();
/**
* 组合继承的优化方式2
*/
function Parent5 (){
this.name = 'parent5';
this.play = [1,2,3];
}
function Child5 () {
Parent5.call(this); //第一次
this.type = 'child5';
}
// 第二次
Child5.prototype = Object.create(Parent5.prototype);
Child5.prototype.constructor = Child5;