javaScript继承的方式(六种)

继承方式

js中继承的方式有六种:
原型链,盗用构造函数,组合继承,原型式继承,寄生式继承,寄生式组合继承

1.原型链

原型链的思想:实例化父类赋值给子类构造函数的原型,从而达到共享父类的方法和属性的目的。
原型链有两个问题(原型链不会单独使用):

  1. 在父类使用引用值会导致继承该父类的子类共享该引用值的指针
  2. 子类不可以向父类传参数
/*原型链实现继承的实现方式*/
function Paren(){
  this.name="小明";
}
Paren.prototype.sayName=function(){
  console.log(this.name)
}

function Child(){
  this.age = 12;
}
Child.prototype = new Parent()
Child.prototype.sayAge=function(){
  console.log(this.age);
}
const instance = new Child();

在父类使用引用值会导致继承该父类的子类共享该引用值的指针

function Paren(){
  this.friends = ["friend1","friend2","friend3"];
}
function Child(){}
Child.prototype = new Paren();//因为在这一步的时候Child.prototype.friend存的是引用值

let instance1 = new Child();
let instance2 = new Child();
instance1.friends.push("friendN");
console.log(instance2.friends);//["friend1","friend2","friend3","friendN"]
console.log(instance1.friends === instance2.friends);//true (引用值相等)

2.盗用构造函数

盗用构造函数的思想:在子类构造函数中调用父类构造方法,this的指向指向子类
解决的问题:传参问题
存在的问题(盗用构造函数不会单独使用):

  1. 子类不能访问父类原型的方法
  2. 必须在构造函数里面定义方法,导致方法没有办法复用(因为每次都执行一次父类构造方法)
/*盗用构造函数实现继承的实现方式*/
function Paren(name){
  this.name = name;
}
function Child(name,age){
  Paren.call(this,name)
  this.age = age;
}

3.组合继承

组合继承的思想:结合原型链和盗用构造函数的优点,使用原型链共享方法,使用盗用构造函数共享属性;
解决的问题:子类可以向父类传递参数,父类的方法可以复用

function Parent( name ){
	this.name = name;
}
Parent.prototype.sayName = function(){
	console.log(this.name)
}
function Child( name ,age){
	Parent.call(this,name)
	this.age = age;
}
Child.prototype = new Parent();
Child.prototype.sayName = function(){
	console.log(this.age)
}

4.原型式继承

出发点:即使不自定义类型也可以通过原型实现对象之间的信息共享

/*核心*/
function object( o ) {
	let F = function(){};
	F.prototype = o;
	return new F()
}

/*等同于*/
Object.create();

5.寄生式继承

寄生式继承同样适合主要关注对象,而不在乎类型和构造函数的场景。和原型式继承很像

function Child (org) {
	const clone = object(org);//新建一个对象
	clone.sayName = function(){ //增强对象属性
		console.log("hello")
	}
	return clone; //返回对象
}

6.寄生式组合式继承

组合继承:

function Parent( name ){
	this.name = name;
}
Parent.prototype.sayName = function(){
	console.log(this.name)
}
function Child( name ,age){
 	// 第一次执行父类构造函数,获取父类属性
	Parent.call(this,name);
	this.age = age;
}
// 第二次执行父类的构造函数,导致原型上会有父类的属性和方法
// 这次我们只需要获取方法,是不需要获取属性的
// 所以可以只拷贝原型上的方法即可
Child.prototype = new Parent();
Child.prototype.sayName = function(){
	console.log(this.age)
}

从组合继承可以看出,执行的时候调用了两次父类的构造函数,存在效率问题

function copyPrototype( parent, child ) {
	const childPrototype = {
		constructor:child,// 2.所以在这里以添加构造函数的方式给增强
		...parent.prototype,
	}
	child.prototype = childPrototype ;//1.直接赋值会导致child的constructor丢失
}
function Parent( name ){
	this.name = name;
}
Parent.prototype.sayName = function(){
	console.log(this.name)
}
function Child( name ,age){
	Parent.call(this,name);//第一次执行父类构造函数
	this.age = age;
}
// Child.prototype = new Parent();//第二次执行父类的构造函数

copyPrototype(Parent,Child);//通过拷贝prototype和增强构造函数;不用调用构造方法

Child.prototype.sayName = function(){
	console.log(this.age)
}

总结

。。。待更新

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值