JS中的继承(下)

原型式继承函数

这种模式要从道格拉斯·克罗克福德(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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值