原型式继承函数
这种模式要从道格拉斯·克罗克福德(Douglas Crockford,著名的前端大师,JSON的创立者)在2006年写的
一篇文章说起: Prototypal Inheritance in JavaScript(在JS中使用原型式继承)。
在这篇文章中,它介绍了一种继承方法,而且这种继承方法不是通过构造函数来实现的.为了理解这种方式,我们先再次回顾一下JavaScript想实现继承的目的:重复利用另外一个对象的属性和方法。以我上一篇文章中的例子来说,也就是student对象的原型指向了person对象。没读过我上一篇文章可以访问JS中继承的方法(上)。
原型式继承函数的案例
方式1
var obj = {
name : 'why',
age : 18
}
function createObject(o){
function Fn(){};
Fn.prototype = o
var newObj = new Fn()
return newObj
}
//info对象的原型要指向obj
var info = createObject(obj)
console.log(info); //{}
console.log(info.__proto__); //{ name: 'why', age: 18 }
方式2
var obj = {
name : 'why',
age : 18
}
// 原型式继承函数
function createObject(o){
var newObj = {} //
Object.setPrototypeOf(newObj,o)
return newObj
}
//info对象的原型要指向obj
var info = createObject(obj)
console.log(info); //{}
console.log(info.__proto__); //{ name: 'why', age: 18 }
方式3(最常用的)
var obj = {
name : 'why',
age : 18
}
//info对象的原型要指向obj
var info = Object.create(obj)
console.log(info); //{}
console.log(info.__proto__); //{ name: 'why', age: 18 }
寄生式继承(利用工厂函数)
它的弊端其实也就是工厂函数的弊端,在我之前的文章里有介绍过工厂模式批量创建对象的缺点。
//把原生式继承放到工厂函数中
var personObj = {
runing:function(){
console.log('runing');
}
} //原型式继承
//工厂函数
function createStudent(name){
var stu = Object.create(personObj)
stu.name = name
stu.studying = function(){
console.log('studying~');
}
return stu
}
var stuObj = createStudent("harry") //弊端,方法有重复,并且工厂函数并不是通过new,并且不能明确类型
寄生组合式继承
function Person(name,age,friends){
this.name = name
this.age = age
this.friends = friends
}
Person.prototype.running = function(){
console.log('running~');
}
Person.prototype.eating = function(){
console.log('eating~');
}
function Student(name,age,friends,sno,score){
Person.call(this,name,age,friends)
this.sno = sno
this.score = score
}
//创建一个新的对象,让原型指向这个新对象,并且新的对象指向person的原型的
Student.prototype = Object.create(Person.prototype) //这里Student.prototype找不到就会顺着原型链往上找,找到__proto__
Object.defineProperty(Student.prototype,"constructor",{
enumerable:false,
configurable:true,
writable:true,
value:Student
})
Student.prototype.studying = function(){
console.log("studying~");
}
var stu = new Student("why",18,["lebro"],111,100)
console.log(stu);
stu.studying()
stu.running()
stu.eating()
优化的寄生组合式继承
封装一个继承的工具类
function inheritPrototype(SubType,SuperType){
SubType.prototype = Object.create(SuperType.prototype)
Object.defineProperty(SubType.prototype,"constructor",{
enumerable:false,
configurable:true,
writable:true,
value:SubType
})
}
function Person(name,age,friends){
this.name = name
this.age = age
this.friends = friends
}
Person.prototype.running = function(){
console.log('running~');
}
Person.prototype.eating = function(){
console.log('eating~');
}
function Student(name,age,friends,sno,score){
Person.call(this,name,age,friends)
this.sno = sno
this.score = score
}
inheritPrototype(Student,Person) //调用继承的工具类函数
Student.prototype.studying = function(){
console.log("studying~");
}
var stu = new Student("why",18,["lebro"],111,100)
console.log(stu);
stu.studying()
stu.running()
stu.eating()
来自本人掘金文章
https://juejin.cn/post/7111673741846773797