js如何实现继承,详解原型链

使用js实现继承,主要是依靠原型链实现的

原型链

想要知道原型链是什么,先了解构造函数,原型,与实例之间的关系

  1. 构造函数:可用来创建特定类型的对象。
    构造函数与其他函数的区别是在于调用方式的不同。
    使用new操作符来调用的函数都是构造函数,函数名默认以大写字母开头
  2. 实例:以构造函数的初始化对象,通过用new操作符
  3. 原型:每个函数一旦被创建就有一个prototype属性(原型),是实例的原型对象

构造函数,原型,与实例之间的关系就是:每个构造函数都有一个原型对象,而实例又指向原型对象

现在我们再来看,什么是原型链?
把一个A类型原型对象等于B类型的实例。此时,A类型原型对象指向B类型原型对象,B类型原型对象指向B构造函数,当实例化一个A构造函数时,他们之间的关系就是:
实例A->A构造函数->A原型对象->B实例->B构造函数->B原型对象
这样的层级递进就是原型链,同时我们也可以看到A继承了B。代码如下:

function Aclass() { 
	this.Aname = "a"; 
} 
Aclass.prototype.getAName = function() { 
	alert(this.Aname);
} 
function Bclass() { 
	this.Bname = "b"; 
} 
Bclass.prototype = new Aclass(); 
Bclass.prototype.getBName = function() { 
	alert(this.Bname); 
} 
var newObj = new Bclass(); 
newObj.getAName() ;//a
newObj.getBName() ;//b
console.log(newObj)

如此可见,原型链实现了继承,但是它也有缺点
一个是还记得上一章使用原型模式实现类中,原型包含像array这样引用类型值的原型属性时会被共享,例如:

Aclass.prototype.arr = [“A”];

var newObj1 = new Bclass();
newObj1.arr.push(“B”);
console.log(newObj1.arr);//[“A”,“B”]
var newObj2 = new Bclass();
console.log(newObj2.arr);//[“A”,“B”]
二是在创建B类型(子类)实例时,无法向A类型(父类)构造函数中传递参数

借用构造函数(伪造对象 || 经典继承)

在B类型(子类)构造函数内部调用A类型(父类)构造函数

function Aclass(name) { 
	this.Aname = [name]; 
} 
function Bclass() { 
	Aclass.call(this,"a")
} 
var newObj = new Bclass(); 
newObj.Aname.push("newObj");
console.log(newObj.Aname) // ["a","newObj"]
var newObj2 = new Bclass(); 
console.log(newObj2.Aname) // ["a"]

这个例子中我们通过call"借调"了Aclass(父类)的构造函数(也可以用apply)。
优点:解决了原型上共享引用类型属性的问题,能够传递参数
缺点:无法共享方法,每次实例化重新创建

组合继承(伪经典继承)

将原型链和借用构造函数组合到一块,发挥两者之长。使用原型链实现对原型属性和方法的继承,使用借用构造函数实现对实例属性的继承。组合达到既可以实现函数复用,又能在每个实例有自己的属性。看下面的例子:

function Aclass(name) { 
	this.name = name; 
	this.arr = ["A"];
} 
Aclass.prototype.sayName = function() {
	alert(this.name);
}
function Bclass(name,s) { 
	Aclass.call(this,name);
	this.string = s;
} 
Bclass.prototype = new Aclass();
Bclass.prototype.constructor = Bclass;
Bclass.prototype.sayString = function() {
	alert(this.string)
}
var newObj = new Bclass("newObj", "Hello");
newObj.arr.push("B");
console.log(newObj.arr) 	//["A","B"]
newObj.sayName(); 	//"newObj"
newObj.sayString()		//"Hello"

var newObj2 = new Bclass("newObj2 ", "Bye");
newObj2 .arr.push("C");
console.log(newObj2 .arr) 	//["A","C"]
newObj2 .sayName(); 	//"newObj2 "
newObj2 .sayString()		//"Bye"
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值