JavaScript面向对象 -继承

原型链

原型链是什么

构造函数或构造器具有prototype属性,对象具有__ proto__ 属性, 这就是之前学习的原型。

如果构造函数或对象A,A的原型指向构造函数或对象B,B的原型再指向构造函数或对象C,以此类推,最终的构造函数或对象的原型指向Object的原型。由此形成一条链状结构, 被称之为原型链。

按照上述的描述,在B中定义的属性或方法,可以直接在A中使用并不需要定义。这就是继承,它允许每个对象来访问其原型链上的任何属性或方法。

原型链是ECMAScript标准中指定的默认实现继承的方式。

原型链实现继承

function A(){
	this.name = "a";
	this.toString = function(){return this.name};
}
function B(){
	this.name = "b";
}
function C(){
	this.name = "c";
	this.age = 18;
	this.getAge = function(){return this.age};
}
B.prototype = new A();
C.prototype = new B();

上述代码实现的示意图如下:

只继承于原型

处于对效率的考虑,尽可能地将属性和方法添加到原型上。可以采取以下方式:

  • 不要为继承关系单独创建新对象。
  • 尽量减少运行时的方法搜索。

根据上述方式更改后,代码如下:

function A(){}
A.prototype.name = "a";
A.prototype.toString = function(){return this.name};

function B(){}
B.prototype = A.prototype;
B.prototype.name = "b";

function C(){}
C.prototype = B.prototype;
C.prototype.name = "c";
C.prototype.age = 18;
C.prototype.getAge = function(){return this.age};

原型链的问题

原型链:虽然很强大,用它可以实现JavaScript中的继承,但同时也存在着一些问题。

  • 原型链实际_上是在多个构造函数或对象之间共享属性和方法。
  • 创建子类的对象时,不能向父级的构造函数传递任何参数。

综上所述,在实际开发中很少会单独使用原型链。

继承

继承

所谓原型式继承,就是定义一个函数, 该函数中创建一个临时性的构造函数, 将作为参数传入的对象作为这个构造函数的原型,最后返回这个构造函数的实例对象。

function object(o){
	function F(){}
	F.prototype = o;
	return new F();
}

根据原型式继承所总结的object()函数实现继承,如下代码示例:

var person = {
	name : "cucu",
	friends : ["pingping","mumu"]
}

var anotherPerson = object(person);
anotherPerson.friends.push("momo");

console.log(anotherPerson.friends);// pingping,mumu,Rob

这种原型式继承要求必须具有一个对象可以作为另一个对象的基础。

上述的原型式继承,也可以利用Object的create()方法替代自定义的object()函数,从而实现规范化。

var person = {
	name : "cucu",
	friends : ["pingping","mumu"]
}

var anotherPerson = object.create(person);
anotherPerson.friends.push("momo");

console.log(anotherPerson.friends);// pingping,mumu,Rob

注意:原型式继承具有与原型链同样的问题。

借助构造函数

无论是原型链还是原型式继承,都具有相同的问题。想要解决这样的问题的话,可以借助构造函数(也可以叫做伪造对象或经典继承)。

这种方式实现非常简单,就是在子对象的构造函数中调用父对象的构造函数。具体可以通过调用apply()和call()方法实现。

apply()和call()方法都允许传递指定某个对象的this。对于继承来讲,可以实现在子对象的构造函数中调用父对象的构造函数时,将子对象的this和父对象的this绑定在一起。

根据上述描述,借助构造函数实现继承,如下代码示例:

function SuperType(){
	this.color = ["red","green","blue"];
}

function SubType(){
	// 继承了SuperType
	SuperType.call(this);
	// 或 SuperType.apply(this,arguments);
}

var instance = new SubType();
instance.color;// red,green,blue

组合方式继承

组合继承,也叫做伪经典继承,指的是将原型链或原型式继承和借助构造函数的技术组合在一起,发挥二者长处的一种继承方式。

具体实现的思路就是:

  • 使用原型链或原型式继承实现对原型的属性和方法的继承。
  • 通过借助构造函数实现对实例对象的属性的继承。

这样,既通过在原型上定义方法实现了函数的重用,又可以保证每个对象都有自己的专有属性。

根据上述描述,组合方式继承,如下代码示例:

function SuperType(name){
	this.name = name;
}
SuperType.prototype.sayMe = function(){
	console.log(this.name);
}

function SubType(name,age){
	SuperType.call(this,name);// 继承属性
	this.age = age;
}
SubType.prototype = SuperType.prototype;// 继承方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值