原型链继承和借用构造函数继承存在的问题

1.原型链继承

//原型对象上的属性和方法都能被实例对象共享

function Animal(){
    this.name = 'ale';
    this.color=['red','yellow'];
};
Animal.prototype.sayName=function (){
  return this.name;
};


function Dog () {
};

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;

var d1=new Dog();
console.log(d1.name); //打印ale
console.log(d1.sayName);//打印出函数
d1.color.push('blue');
console.log(d1.color); //打印(3) ["red", "yellow", "blue"]
console.log(d1.color); //打印(3) ["red", "yellow", "blue"]

//问题:1.不能传参 2.父类中的属性和方法一旦赋值给子类的原型属性,这些父类的属性和方法都属于子类的共享属性,修改引用类型的数据会影响所有子实例的值

2.借用构造函数继承

解决原型对象中包含引用类型值所带来问题
//在子类的构造函数内部中调用父类的构造函数

function Animal(name){
    this.name = name;
    this.color=['red','yellow'];
};
Animal.prototype.sayName=function (name){
  return this.name;
};

function Dog (name) {
	Animal.call(this,name)
};

var d1 = new Dog('lll');
var d2 = new Dog('555');

 d1.color.push('blue');
 
 console.log(d1.color);//(3) ["red", "yellow", "blue"]
 console.log(d1.name);//lll

 console.log(d2.color);//(2) ["red", "yellow"]
 console.log(d2.name);//555
 
 console.log(d1.sayName);//undefined

缺点:不能继承父类的原型对象上的方法

解决的方法–组合继承

function Animal(name){
    this.name = name;
    this.color=['red','yellow'];
};
Animal.prototype.sayName=function (name){
  return this.name;
};


function Dog (name) {
	//让父类的属性值继承下来,修改父类的引用类型的值,不会影响其他实例的引用类型的值
	Animal.call(this,name)
};
//重写原型对象,把父类共享的方法继承下来
Dog.prototype = new Animal();
Dog.prototype.constructor=Dog;

var d1 = new Dog('lll');
var d2 = new Dog('555');

 d1.color.push('blue');

 console.log(d1.color);   //打印出(3) ["red", "yellow", "blue"]
 console.log(d1.name);   //打印出lll

 console.log(d2.color);   //打印出(2) ["red", "yellow"]
 console.log(d2.name);   //打印出555

 console.log(d1.sayName);   //打印出ƒ(name){return this.name;}

//问题:会调用父类构造函数2次

**

寄生组合式继承方式

**

```css
function Animal(name){
    this.name = name;
    this.color=['red','yellow'];
};
Animal.prototype.sayName=function (name){
  return this.name;
};


function Dog (name) {
	//让父类的属性值继承下来,修改父类的引用类型的值,不会影响其他实例的引用类型的值
	Animal.call(this,name)
};
//重写原型对象,把父类共享的方法继承下来
Dog.prototype = Object.create(Anmail.prototype) //解决了组合方式重复访问父类构造函数
Dog.prototype.constructor=Dog;

var d1 = new Dog('lll');
var d2 = new Dog('555');

 d1.color.push('blue');

 console.log(d1.color);    //打印出(3) ["red", "yellow", "blue"]
 console.log(d1.name);   //打印出lll

 console.log(d2.color);    //打印出(2) ["red", "yellow"]
 console.log(d2.name);   //打印出555

 console.log(d1.sayName);    //打印出ƒ(name){return this.name;}

**

5.多线继承

function Person(name){
    this.name = name;
};
Person.prototype.sayName=function (name){
  return this.name;
};

function Parent(age){
    this.age= age;
};
Parent.prototype.sayAge=function (age){
  return this.age;
};

function Me(name,age) {
	Person.call(this,name);
	Parent.call(this,age);
};
//重写原型对象,把父类共享的方法继承下来
Me.prototype = Object.create(Person.prototype) //解决了组合方式重复访问父类构造函数
Me.prototype.constructor = Me;
Object.assign(Me.prototype ,Parent.prototype )//把Parent.prototype的方法复制到Me.prototype,防止重复复制导致覆盖

var d1 = new Me('ggd',28);

**特点和缺点总结:
1.原型链继承:
特点:重写了子类的原型对象,父类的原型对象上的属性和方法都被继承下来
缺点:父类上的所有属性和方法都被子类实例共享,一旦修改了引用类型的值,其他子类的实例的引用类型的值会被修改;当实例化子类的时候不能传递参数到父类

2.借用构造函数继承:
特点:通过子类函数内部调用父类的构造函数(call(),bind(),apply()),改变父类中的this指向
优点:把父类中的属性继承下来,还能够传参
缺点:父类的原型对象上的方法不能继承

3.组合是继承
特点:结合了原型链继承和借用构造函数继承的优点
原型链继承:父类的公有方法继承下来
借用构造函数继承:实例属性被子类继承下来
缺点:调用了2次父类构造函数
4.寄生组合式继承
原理:var Dog.prototype=Object.create(Anmail.prototyope)
把父类的的原型对象赋给子类的原型对象

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值