欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

javaScript中的对象的继承代码解析

程序员文章站 2022-10-27 15:42:31
借用构造函数实现继承 function supertype(){ this.colors = ["red","blue","green...

借用构造函数实现继承

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

function subtype(){
    //在子类构造函数中调用父类构造函数(同时这种方式支持向父类构造函数传参)
    supertype.call(this);
    //supertype.call(this,arg1,arg2)
    //supertype.apply(this,args)
}

作用:借用构造函数方式是在新的subtype对象上面执行supertype中定义的初始化代码,针对在原型中的引用类型,每一个实例都有自己的一个副本(可以清除原型中包含引用类型值的问题)

问题:仅仅是借用构造函数,无法避免构造函数模式存在的问题,方法都是在构造函数中定义,因此函数复用就无从谈起了

组合继承(经典继承)

这种方式的思想是使用原型实现对原型属性和方法的继承,而通过构造函数实现对实例属性的继承

function supertype(name){
    this.name = name;
    this.colors = ["red","blue","green"];
}
//父类原型的属性和方法
supertype.prototype.sayname = function(){
    alert(this.name);
}
function subtype(name,age){
    //通过调用父类的构造方法继承父类的实例属性
    supertype.call(this,name);
    //自己的实例属性
    this.age = age;
}
//通过原型方式继承父类
subtype.prototype = new supertype();
//重写constructor属性
subtype.prototype.constructor = subtype;
subtype.ptototype.sayage = function(){
    alert(this.age);
}

组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,是javascript中最常用的一种继承模式。

问题:组合继承会导致父类构造方法被调用两次,当我们在创建子类原型的时候会调用一次,第二次是我们调用子类构造方法的时候里面会调用一次。

原型式继承

借助原型可以基于已有对象创建新的对象,同时还不必因此创建自定义类型

var person = {
    name:"sc",
    friends:["nix","unix","windows","ubantu"]
}
function object(o){
    //临时构造函数
    function f(){};
    //继承
    f.prototype = o;
    return new f();
}
var p1 = object(person);
p1.friends.push("p1's friends");
p1.name = "p1";

var p2 = object(person);
p2.friends.push("p2's friends");
p2.name = "p2";

console.log(p1.name);//p1
console.log(p2.name);//p2
console.log(p1.friends);//["nix", "unix", "windows", "ubantu", "p1's friends", "p2's friends"]
console.log(p2.friends);//["nix", "unix", "windows", "ubantu", "p1's friends", "p2's friends"]

上面的原型方式在ecmscript5中通过新增object.create()方法规范化了,该方法接收两个参数,第一个为用作新对象原型的对象和(可选的)一个新对象定义额外属性的对象。

问题:原型式继承同样没有解决引用问题

寄生式继承

寄生式继承思路与寄生构造函数类似,也就是创建一个仅仅用于封装继承过程的函数,该函数内部以某种方式来增强对象,最后再像真正的地是它做了所有的工作一样返回对象。

//寄生式继承
function createanother(original){
    //调用函数创建一个新的对象
    var clone = object(original);
    //以某种方式来增强这个对象
    clone.sayhi = function(){
        alert("hi");
    }
    return clone;
}
//上面的object()函数不是必须的,每一个能够返回新对象的函数都可以适用这个模式

问题:可以使用寄生继承来为对象添加函数,会由于不能做到函数复用而降低效率,这一点会与构造函数模式类似。

寄生组合式继承

寄生组合式继承解决组合继承中两次调用父类构造函数的问题。寄生组合式继承,也就是通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。

思路是:不必为了指定子类的原型而调用超类的构造函数,我们所需要的无非就是超类型原型的一个副本而已,本质上,就是使用寄生继承来继承超类原型,然后再将结果指定给子类型的原型

function inheritprototype(subtype,supertype){
    //创建对象
    var prototype = object(supertype.prototype);
    //增强对象
    prototype.constructor = subtype;
    //指定对象
    subtype.prototype = prototype;
}