您的位置:首页 > Web前端 > JavaScript

JS继承的几种方式

2018-03-09 15:40 429 查看
1. 借助构造函数实现继承

function Parent() {
this.name = 'parent';
}
function Child() {
Parent1.call(this);
this.type = 'child';
}


缺点:只能实现部分继承。
Child
只能继承
Parent
构造函数里面的属性。不能继承
Parent
原型链上的。

function Parent1() {
this.name = 'parent1';
}
Parent1.prototype.say = function() {
};
function Child1() {
Parent1.call(this);
this.type = 'child1';
}
console.log(new Child1(), new Child1().say());




2. 借助原型链实现继承

function Parent() {
this.name = 'parent';
}
function Child() {
this.type = 'child';
}
Child.prototype = new Parent();


缺点:实例化两个类,修改第一个实例的属性,会牵动第二个实例的属性变化。原因是两个实例的原型对象引用的是同一个对象,都是父类的实例对象。而改变的方法在父类的实例对象上,而且是引用类型。

function Parent2() {
this.name = 'parent2';
this.play = [1, 2, 3];
}

function Child2() {
this.type = 'c
4000
hild2';
}
Child2.prototype = new Parent2();

var s1 = new Child2();
var s2 = new Child2();
s1.play.push(4);
console.log(s1.play, s2.play);




3. 组合方式

function Parent() {
this.name = 'parent';
}
function Child() {
Parent.call(this);
this.type = 'child';
}
Child.prototype = new Parent();


解决了上面遗留下来的缺点

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();
s3.play.push(4);
console.log(s3.play, s4.play);




缺点:父类构造函数执行了两次。

4. 组合继承的优化1

function Parent() {
this.name = 'parent';
this.play = [1, 2, 3];
}
function Child() {
Parent.call(this);
this.type = 'child';
}
Child.prototype = Parent.prototype;
var s5 = new Child();
var s6 = new Child();


不仅能把构造体内的函数属性拿到,还可以把原型链上的属性拿到。

缺点:用constructor判断实例是哪个构造函数实例化的失效了。上面构造函数的方式也有同样的问题。他们的
constructor
都指向父类。

function Parent4() {
this.name = 'parent4';
this.play = [1, 2, 3];
}

function Child4() {
Parent4.call(this);
this.type = 'child4';
}
Child4.prototype = Parent4.prototype;
var s5 = new Child4();
var s6 = new Child4();

console.log(s5 instanceof Child4, s5 instanceof Parent4);
console.log(s5.constructor);




5. 组合继承的优化2

function Parent() {
this.name = 'parent5';
this.play = [1, 2, 3];
}

function Child() {
Parent.call(this);
this.type = 'child5';
}
// 产生一个中间对象隔离`Child`的`prototype`属性和`Parent`的`prototype`属性引用的同一个原型。
Child.prototype = Object.create(Parent.prototype);
// 给Child的原型对象重新写一个自己的constructor。
Child.prototype.constructor = Child;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: