继承的概念以及原型和继承的关系

本文详细探讨了JavaScript中的原型与继承机制,包括默认原型、原型链的工作原理,以及如何通过实例化实现继承。同时,文章指出在原型上添加方法时应注意避免属性共享问题,并展示了如何覆盖或扩展父类方法。最后,提到了原型链可能导致的问题,如引用类型的属性共享和无法在构造时传参。
摘要由CSDN通过智能技术生成

目录

继承

默认原型

原型与继承的关系

关于原型上的方法

原型链的问题


继承

先看一个栗子:

function SuperType(){
    this.property = true   //注意这个property不属于原型上的属性,会在它的实例对象身上
}

Demo1.prototype.getSuperValue = function(){
    return this.property
}

function SubType(){
    this.subproperty = false
}
 
SubType.prototype = new SuperType();   //SubType的原型是SuperType的实例对象

SubType.prototype.getSubValue = function()   //给SubType的原型上添加方法
{
return this.subproperty
}

let instance = new SubType();
console.log(instance.getSuperValue)

这个栗子特殊之处在于:SubType的原型是SuperType的实例对象。

得出以下结论,

SubType.Prototype._proto_ == SuperType.Prototype

instance._proto_ == SubType.Prototype

 也就是说 SubType 的实例(instance)不仅能从SuperType的实例(SubType) 中继承属性和方法,而且还与SuperType的原型挂上了钩

注意点1:getSuperValue才是定义在原型上的方法,会被它的实例对象(SubType.Prototype)所共享,但是property不是定义在原型上的属性,它只会储存在它的实例对象身上。

注意点2:SubType.prototype 的constructor属性被重写为指向SuperType,所以Instance.constructor也指向SuperType.

原型链扩展了原型搜索机制,先在实例本身查找属性和方法,没有就去原型上搜索,也没有就去原型的原型上搜索。

instance.getSuperValue()  经过了三次搜索:

instance -> SubType.prototype -> SuperType.prototype

默认原型

默认情况下,所有引用类型都继承自Object,这也是通过原型链实现的。

任何函数的默认原型都是一个Object的实例,这就意味着实例内部有个指针[[Prototype]]也就是_proto_属性会指向Object.prototype。所以自定义类型能够继承toString() 、ValueOf()等所有默认方法。

回到这个栗子上,insatnce.toString()方法能被调用,实际上它是调用的Object.prototype身上的方法。

instance是 SubType 的实例,SubType 继承 SuperType,SuperType 继承 Object

原型与继承的关系

有两种方法确定原型和实例是否有关系,有两种方法

instanceof()     

 isPrototypeof()

console.log(instance instanceof  Object);    //true

console.log(instance instanceof  SubType),   //true

conole.log(Object.prototype.isPrototype(instance)) ;  //true

关于原型上的方法

子类有时候需要覆盖父类的方法,或者增加父类没有的方法

function Father(){
this.name = "jack"
}
Father.prototype.sayName1= function(){
    return this.name
}

function children(){
    this.name = "jerry"
}
children.prototype = new Father();

//在子类的原型上添加父类没有的方法
children.prototype.sayName2 = funtion(){
    return this.name
};
//覆盖已有方法
children.prototype.sayname1 = function()
{
    return  this.name
}
let instance = new children();
console.log(insatnce.sayName1())    //"jerry"  

在这段代码中,instance调用的sayName1方法,正常来讲它应该会根据原型链查找规则找到Father原型上的方法,但是这个方法被children原型上的同名方法所屏蔽了。

值得注意的是:如果以字面量方式创建原型方法会破坏之前的原型链,因为这相当于重写了原型链。

function SuperType(){
    this.property = true;
}
SuperType.prototype.getSuperValue = function(){
    return this.property
};
function SubType(){
    this.subproperty = false;
}
//实现继承
SubType.prototype = new SuperType();
//通过字面量方式创建对象,上一行无效
SubType.prototype= {
    getSubValue()
    {
    return this.subproperty;
    },
    otherMethods(){
    return false
}

}

let instance = new SubType();
console.log(instance.getSuperValue)   //报错,找不到这个方法

子类的原型被对象字面量所覆盖了。覆盖后的原型是Object的实例,不再是SuperType的实例了。就不可能继承SuperType上的属性和方法了。

原型链的问题

问题1就是之前的属性是引用类型时,会被所有实例所共享;

问题2 子类型在实例化时不能给父类传递参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值