JavaScript基础系列之——继承

一、基本概念:

    JavaScript基于原型实现面向对象特性,在JS编程中,面向对象的继承是重点,本文将从简单开始介绍JS的继承。


二、继承方式:

1、借助构造函数实现继承:

function Parent1(){

    this.name = 'parent1'

}

function Child1(){

    Parent1.call(this)

    this.type = 'child1'

}

    父级构造函数在子级构造函数内使用call、apply方法,将自身的this指向子级实例,并执行,从而使得子级实例后拥有父级的属性;

    简单,但是父级原型上的属性无法继承;

2、借助原型链继承:

function Parent2(){

    this.name = 'parent2';

}

function Child2(){

    this.type = 'Child2';

}

Child2.prototype = new Parent2();

console.log(new Child2());

    Child2构造函数的属性prototype指向一个原型对象,可以任意更改,将 Parent2 的实例作为Child2的原型对象,于是,当 new Child2 后生成的实例, 其 __proto__ 指向的原型对象就是 Child2的prototype指向的Parent2实例

    这样,子实例共享同一个继承的实例的属性,更改其中之一,会改变所有;没有隔离;

3、组合继承:

function Parent3(){

    this.name = 'parent3';

    this.play = [1,2,3,4];

}

function Child3(){

    Parent3.call(this);

    this.type = 'child3';

}

Child3.prototype = new Parent3();

var c31 = new Child3();

var c32 = new Child3();

c31.play.push(5);

console.log(c31, c32);

console.log(c31.constructor)

    弥补了构造函数和原型链继承的缺点, 但是,父级构造函数体执行了两次,生成的实例无法判断实例源(实例的constructor属性指向父级的构造函数)。(详细见组合优化1)

4、组合继承的优化1:

function Parent4(){

    this.name = 'parent4';

    this.play = [1,2,3,4];

}

function Child4(){

    Parent4.call(this);

    this.type = 'child4';

}

Child4.prototype = Parent4.prototype;

var c41 = new Child4();

var c42 = new Child4();

c41.play.push(5);

console.log(c41, c42);

console.log(c41 instanceof Child4, c41 instanceof Parent4); // true true

console.log(c41.constructor); // 指向 Parent4

    弥补了组合继承 执行 2次的缺点, 但是,生成的实例,使用instanceof 判断的时候,无法判断该对象是由Parent5实例化或Child5实例化 , 使用实例的constructor属性(实际为__proto__指向原型对象上的属性),指向 Parent5.... 于是无法判断该实例是由哪个构造函数实例化的;(组合继承都有这个缺点)

5、组合继承的优化2:

function Parent5(){

    this.name = 'parent5';

    this.play = [1,2,3,4];

}

function Child5(){

    Parent5.call(this);

    this.type = 'child5';

}

Child5.prototype = Object.create(Parent5.prototype); // 创建中间对象

Child5.prototype.constructor = Child5; // 中间对象的构造函数更改constructor

var c51 = new Child5();

var c52 = new Child5();

c51.play.push(5);

console.log(c51, c52);

console.log(c51 instanceof Child5, c51 instanceof Parent5);

console.log(c51.constructor);

    弥补了前面继承方式的缺点;完美~~~~~

你可能感兴趣的:(JavaScript基础系列之——继承)