JS继承的几种方式
2018-03-09 15:40
429 查看
1. 借助构造函数实现继承
缺点:只能实现部分继承。
2. 借助原型链实现继承
缺点:实例化两个类,修改第一个实例的属性,会牵动第二个实例的属性变化。原因是两个实例的原型对象引用的是同一个对象,都是父类的实例对象。而改变的方法在父类的实例对象上,而且是引用类型。
3. 组合方式
解决了上面遗留下来的缺点
缺点:父类构造函数执行了两次。
4. 组合继承的优化1
不仅能把构造体内的函数属性拿到,还可以把原型链上的属性拿到。
缺点:用constructor判断实例是哪个构造函数实例化的失效了。上面构造函数的方式也有同样的问题。他们的
5. 组合继承的优化2
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;