js继承方式

一、原型链继承

父类的实例作为子类的原型,子类继承父类的属性和方法。
优点:简单易懂,代码量少。
缺点: 所有子类实例共享父类的属性和方法,无法在不影响其他实例的情况下进行修改。

function Parent() {
  this.name = 'parent';
}
 
Parent.prototype.sayHello = function() {
  console.log('Hello');
}
 
function Child() {
  this.age = 18;
}
 
Child.prototype = new Parent();
 
var child = new Child();
console.log(child.name); // parent
child.sayHello(); // Hello

二、构造函数继承

为了解决原型链继承牵一发动全实例的缺点,推出了构造函数的继承。
子类的构造函数中调用父类的构造函数,使用call或者apply继承父类的属性。
优点:子类可以独立使用父类的属性。
缺点: 子类无法继承父类原型上的属性和方法。

function Parent () {
	this.name = name;
}
function Child () {
	Parent.call(this);
	this.age = age;
}
var child = new Child('child', 18);
console.log(child.name); // child;
console.log(child.age); // 18;

三、组合继承

为了解决上面两个的问题,组合继承应运而生。
它就是将原型链继承和构造函数结合起来的一种方式。
先调用构造函数继承父类的属性,然后再将父类的实例作为子类的原型,实现父类原型上属性和方法的继承。
优点:既可以使用父类的属性,也可以使用父类的方法。
缺点:调用了两次父类构造函数。

function SuperType (name) {
	this.name = name;
	this.colors = ['red', 'blue'];
}
SuperType.prototype.sayName = function () {
	console.log(this.name);
}
function subType (name, age) {
	// 继承属性
	SuperType.call(this, name);
	this.age = age;
}
// 继承父类的方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){ 
 alert(this.age); 
}; 
var instance1 = new SubType("Nicholas", 29); 
instance1.colors.push("black"); 
alert(instance1.colors); //"red,blue,black" 
instance1.sayName(); //"Nicholas"; 
instance1.sayAge(); //29 
var instance2 = new SubType("Greg", 27); 
alert(instance2.colors); //"red,blue" 
instance2.sayName(); //"Greg"; 
instance2.sayAge(); //27

四、原型式继承

通过创建一个临时性的构造函数,将传入的对象作为构造函数的原型,实现属性和方法的继承。

function createObj(obj) {
	function F() {}
	F.prototype = obj;
	return new F();
}
var parent = {
  name: 'parent',
  sayHello: function() {
    console.log('Hello');
  }
};
 
var child = createObj(parent);
console.log(child.name); // parent
child.sayHello(); // Hello

优点:可以继承一个对象的属性和方法,比较灵活。
缺点: 所有实例都会共享原型对象。

五、寄生式继承

是原型式继承的基础上,增强对象。
先创建一个父类的副本,然后修改这个副本,最后将修改后的副本赋值给子类。

function createObj(obj) {
  var clone = Object.create(obj);
  clone.sayHi = function() {
    console.log('Hi');
  }
  return clone;
}
 
var parent = {
  name: 'parent',
  sayHello: function() {
    console.log('Hello');
  }
};
 
var child = createObj(parent);
console.log(child.name); // parent
child.sayHello(); // Hello
child.sayHi(); // Hi

优点:可以在继承的基础上增加新的方法或属性,比较灵活
缺点: 无法复用父类的构造函数。

六、寄生组合式继承

组合式继承和寄生式继承的结合体。

  1. 创建一个函数,将函数的原型指向父类。
  2. 子类的原型指向这个函数(继承父类)。
  3. 子类的构造函数指向自己(修正子类构造函数指向)。
   // 实现继承的核心函数
   function inheritPrototype(subType,superType) {
      function F() {};
      //F()的原型指向的是superType
      F.prototype = superType.prototype; 
      //subType的原型指向的是F()
      subType.prototype = new F(); 
      // 重新将构造函数指向自己,修正构造函数
      subType.prototype.constructor = subType; 
   }
   // 设置父类
   function SuperType(name) {
       this.name = name;
       this.colors = ["red", "blue", "green"];
       SuperType.prototype.sayName = function () {
         console.log(this.name)
       }
   }
   // 设置子类
   function SubType(name, age) {
       //构造函数式继承--子类构造函数中执行父类构造函数
       SuperType.call(this, name);
       this.age = age;
   }
   // 核心:因为是对父类原型的复制,所以不包含父类的构造函数,也就不会调用两次父类的构造函数造成浪费
   inheritPrototype(SubType, SuperType)
   // 添加子类私有方法
   SubType.prototype.sayAge = function () {
      console.log(this.age);
   }
   var instance = new SubType("Taec",18)
   console.dir(instance)

优点:最常用的继承模式。
缺点:写法复杂。

ES6继承
class Parent {
  constructor(name) {
    this.name = name;
  }
 
  sayHello() {
    console.log('Hello');
  }
}
 
class Child extends Parent {
  constructor(name, age) {
    super(name);
    this.age = age;
  }
}
 
var child = new Child('child', 18);
console.log(child.name); // child
console.log(child.age); // 18
child.sayHello(); // Hello

ES6的继承方式更加简洁明了,通过class和extends关键字可以直接定义父类和子类,使用super关键字调用父类的构造函数和方法。这种方式避免了手动设置原型和构造函数的步骤,更加符合面向对象编程的思想。

参考链接:https://blog.csdn.net/dlcxycg/article/details/131987415

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值