js的继承

参考:
红皮书

红皮书提到有两种继承方式:接口继承和实现继承,js没有接口继承,因为js没有函数签名
函数签名就是函数的声明信息,包括参数、返回值、调用约定之类,这个调用约定我查了查,大概就是指C里面的_stdcall、__cdecl这种东西(平时真的很少说调用约定这么专业的术语),主要是参数压栈顺序,清栈顺序什么的,了解就行,哪天遇到了再填坑

0.直接使用原型链

```
function superT(){
    this.names = ['11','22'];
}

function subT(){}

subT.prototype = new superT();//也可以把new出来的这个对象赋给一个变量,方便修改

var ins1 = new subT();
var ins2 = new subT();

直接使用原型链进行继承主要有两个问题:
1。无法向父类型传递参数
2。引用类型的变量子类实例是共享的,当然可以在子类实例上自己重新定义,进行覆盖,但是那就失去了继承的意义了,这一篇讨论继承主要就是讨论从父类上获取变量和函数

变量:值类型没问题,引用类型子类实例大家共享
函数:子类实例大家共享,在subT.prototype上面

1.借用构造式

function superT(){
    this.names = ['11','22'];
}

function subT(){
    superT.call(this);//主要就是在子类型构造函数中调用父类型的构造函数
    this.age = 20;
}

var ins1 = new subT();
var ins2 = new subT();

如果要传递参数,可以直接在call的时候把参数传递进去

变量:子类实例大家一人一个,不共享
函数:子类实例大家一人一个,不能共享,在this上

2.组合式

function superT(color){
    this.names = ['11','22'];
    this.color = color;
}

superT.prototype.getName = function(){
    return this.names
}

function subT(color, age){
    superT.call(this, color);//又调用一次superT
    this.age = age;
}

var mid = new superT();//调用一次superT

subT.prototype = mid;

mid.getColor = function(){
    return this.color
}

var ins1 = new subT('red', 20);
var ins2 = new subT('blud', 21);

变量:子类实例大家一人一个,不共享
函数:子类实例共享

注意var mid = new superT();subT.prototype = mid;这两句把superT的属性加到了subT的原型对象上,然后在创建subT的实例时,superT.call又把superT的属性加到了新创建的实例对象上面

3.原型式

名字比较有误导性,不用管,知道是怎么个思路就行

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

var s = {
    name: 's',
    friends: [1,2,3,4],
    sayName:function(){
        return this.name;
    }
}

var a = objectTemp(s);
var b = objectTemp(s);

变量、函数:子类实例共享
Object.create()在接受一个参数进行调用时,结果和objectTemp一样,Object.create()的第二个参数可以接受和Obejct.defineProperties()的相同格式的参数

4.寄生式

function objectSecond(o){
    return o;//这个函数重点是要返回一个对象,也可以在函数中对这个对象进行一些属性的添加
}

function createAnother(o){
    var c = objectSecond(o);
    c.sayAge = function(){
        return 20;
    }
    return c;
}

var s = {
    name: 's',
    friends: [1,2,3,4],
    sayName:function(){
        return this.name;
    }
}

var a = createAnother(s);

如果objectSecond没有做类似原型式继承(第3种)的操作,那么变量和函数就不是共享的

5.寄生组合式

function inheritPrototype(subT, superT){
    var prot = objectTemp(superT.prototype);// 这里的操作是把superT的原型赋给了subT的原型,但是不需要调用一次superT()
    prot.constructor = subT;
    subT.prototype = prot;
}

function superT(color){
    this.names = ['11','22'];
    this.color = color;
}

superT.prototype.getName= function(){
    return this.names
}

function subT(color, age){
    superT.call(this, color);//这里还是需要调用的
    this.age = age;
}

subT.prototype.getColor = function(){
    return this.color
}

inheritPrototype(subT, superT);

六种继承方式,其实基本的就三种,一种是把父类的实例赋给子类的原型,一种是在子类的构造函数里调用父类的构造函数,还有一种是创建一个临时的构造函数,把父类的实例赋给这个临时构造函数的原型,然后返回这个临时构造函数的实例,剩下的就是一些技巧性的组合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值