JavaScript学习记录-继承

一些正统面向对象语言都会用两种方式实现继承:一个是接口实现,一个是继承。而JS只支持继承,不支持接口实现,且实现继承的方式依靠原型链完成。

1、原型链继承

在JavaScript中,一共有两种类型的值,原始值和对象值。每个对象都有一个内部属性[[prototype]],我们通常称之为原型。原型的值可以是一个对象,也可以是null。如果它的值是一个对象,则这个对象也一定有自己的原型。这样就形成了一条线性的链,我们称之为原型链。

function Father(){  //被继承的函数叫做超类型(其他语言相同意思的不同叫法:父类,基类)
    this.name="Tom";
}
function Son(){     //继承的函数叫子类型(子类,派生类)
    this.age=24;
}
// 通过原型链的继承,超类型实例化后的对象实例,赋值给子类型的原型属性
// new Father()会将Father构造里的信息和原型里的信息都交给Son
Son.prototype=new Father();

var demo=new Son();
alert(demo.name);

 通过上例就能先简单的了解继承,Son函数里没有name属性,却通过了继承Father函数里的name属性,可以最终正确返回。

原型链继承流程图

超类型函数的对象实例和原型中都有属性时,继承它的子类型函数返回的这个属性值,就近原则,实例中有就返回,没有就查找原型中。

function Father(){
    this.name="Tom";    //实例对象的属性
}
Father.prototype.name="bert";    //原型中属性

function Son(){ 
    this.age=24;
}

Son.prototype=new Father();

var demo=new Son();
alert(demo.name);    //返回结果Tom

继承的从属关系,接上例,所有的构造函数都继承自Obejct,且继承Object是自动完成的,

var dad=new Father();
var baby=new Son();

alert(baby instanceof Object);
alert(baby instanceof Son);
alert(baby instanceof Father);
alert(dad instanceof Son);	

2、借用构造函数继承(对象冒充继承)

原型中就存在无法传参导致初始化值都一样问题和对于引用类型的共享问题,此处继承也存在这样的问题,为解决此问题,可采用成为对象冒充(伪造对象、经典继承)的技术。

function Demo1(Name,Age){
    this.name=Name;
    this.age=Age;
    this.family=["father","mother","sister"];
}
function Demo2(Name,Age){
    Demo1.call(this,Name,Age);
}

var demo1=new Demo2("bert",24);
alert(demo1.name);    //bert
demo1.family.push("borther");
alert(demo1.family);    //father,mother,sister,borther

var demo2=new Demo2("Tom",25);
alert(demo2.family);    //father,mother,sister

4、组合继承(结合上两种)

借用构造函数虽然解决了刚才两种问题,但没有原型,如果存在方法的话,只能放在构造函数里,多次实例化就会导致方法分配多个内存地址,浪费了内存空间。所有最好方法放在原型里,保证多次实例化只能一个地址。

function Demo1(Name,Age){
    this.name=Name;
    this.age=Age;
    this.family=["father","mother","sister"];
}
Demo1.prototype.run=function(){
    return "Family members are "+this.family+" and "+this.name;
};

function Demo2(Name,Age){
    Demo1.call(this,Name,Age);  //对象冒充
}
Demo2.prototype=new Demo1();     //原型链继承

var demo1=new Demo2("bert",24);
alert(demo1.run());

猜你喜欢

转载自blog.csdn.net/bertZuo/article/details/81944701