详解JS继承

本文详细探讨了JavaScript的多种继承方式,包括原型链继承、构造函数继承、组合继承、实例继承、拷贝继承以及寄生组合继承。分析了各种继承方式的优缺点,如原型链继承无法传递参数,构造函数继承不能复用方法,组合继承可能导致存储空间浪费等。最后,提出寄生组合继承是最佳实践,因为它避免了属性的重复存储。
摘要由CSDN通过智能技术生成

JS继承经常会被问到,这两天准备好好整理一下,梳理下各自的优缺点和注意点,以下代码均为手打(因为吃了一次无工具硬编码的亏),在控制台编译通过, 如有不对,敬请指正,谢谢!
一:原型链继承
原型链继承:
一句话描述:将子类的构造函数原型对象指向父类的实例,从而实现原型链继承

function Father(){
   
	this.showArr = [1,2,3];
	this.showName = 'Father';
}
function Mother(){
   
	this.showArr = [4,5,6];
	this.showName = 'Mother';
}
function Child(){
   
	this.age = 18;
}
var father = new Father();
Child.prototype = father;
Child.prototype.constructor = Child;
var SonA = new Child();
console.log(SonA.showArr);   //[1,2,3]
console.log(SonA.showName);  //Father
console.log(SonA.age); //18
console.log(Child.showName); //undefined 原型链继承只存在与实例对象和原型对象之间,和构造函数无关
var mother = new Mother();
Child.prototype = mother;
console.log(SonA.showName);  //Father SonA._proto_指向并没有改变,还是原来老的,可以参考下面的列子
var SonB = new Child();
console.log(SonB.showArr);   //[4,5,6]
console.log(SonB.showName);  //Mother
SonB.showArr.push(8);        //子类修改了原型中的公用的引用类型值的原型属性
SonB.showName = 'changeName';//子类修改了原型中的公用的非引用类型值的原型属性
var SonC = new Child();
console.log(SonC.showArr);   //[4,5,6,8] 成功改变
console.log(SonC.showName);  //'Mother'  不改变

重点来分析一下这一句:Child.prototype.constructor = Child;
为什么要重写原型对象的constructor呢,其实如下图所示:
在这里插入图片描述
Child.prototype中其实并没有constructor属性,执行这一句是为了为prototype增加constructor属性,并规定其正确的指向。
如下图所示,这样Child.prototype中就有了constructor。但是如果没有写这句,为什么也可以访问到constructor,其实就是根据再原型链上去查找,找到了原型对象上的constructor,也就是Child.prototype.__proto__.constructor(Father)!
在这里插入图片描述
那实现继承时为何总是要修正constructor的指向呢?
引用别人的一段话,写的很好:
constructor其实没有什么用处,只是JavaScript语言设计的历史遗留物。由于constructor属性是可以变更的,所以未必真的指向对象的构造函数,只是一个提示。不过,从编程习惯上,我们应该尽量让对象的constructor指向其构造函数,以维持这个惯例。

例子2:

function myObject(){
   };
var obj1 = new myObject();
myObject.prototype.type = 'old';
var obj2 = new myObject();
console.log(obj1 instanceof myObject);  //true 只是给原型对象myObject.prototype添加了type属性,并没有改变myObject.prototype指向
console.log(obj2 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值