原型链继承

function Car(){
    this.wheel = "wheel";
    this.arr = [1,2];
    this.drive = function (speed){
} } function Bmw(){}; Bmw.prototype = new Car(); //核心 var bmw = new Bmw(); var bmw1 = new Bmw(); console.log(bmw.wheel) //wheel bmw1.arr.push(3); console.log(bmw.arr) //[1,2,3] console.log(bmw1.arr); //[1,2,3]

 

 

核心:把父类的实例化对象赋值给子类原型。

缺点:1、值类型成员不影响,引用类型成员是所有实例对象所共享的,容易被改变。(引用类型成员包括数组、对象、函数);

   2、在创建子类型的实例时,不能向超类型的构造函数中传递参数。(实际上是没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数)

构造函数继承

function Car(direction){
    this.wheel = "wheel";
    this.arr = [1,2];
    this.direction = direction;
    this.drive = function (){
        console.log("方向:"+this.direction);
        console.log("车速:"+this.speed);
    }
}
function Bmw(speed){
    this.speed = speed;
    Car.call(this,"正北");    //核心
};

var bmw = new Bmw(1);
var bmw1 = new Bmw(2);
console.log(bmw.wheel) //wheel

bmw1.arr.push(3);
console.log(bmw.arr) //[1,2]
console.log(bmw1.arr); //[1,2,3]
bmw.drive();  //车速:1
bmw1.drive(); //车速:2

 

核心:在子类中调用call,相当于把父类的实例属性复制一遍给子类。

   解决了原型链的共享和不能传参的缺点。

缺点:由于call相当于把父类函数复制给子类了,所以两个子类并未引用同一个函数,而是每个子类都有一个drive函数。内存浪费,影响性能。

组合继承(常用)

function Car(){
    this.wheel = "wheel";
    this.arr = [1,2];
}
Car.prototype.drive = function(){          //核心
    console.log("车速:"+this.speed);
}
function Bmw(speed){
    this.speed = speed;
    Car.call(this);    //核心
};
Bmw.prototype = new Car();   //核心
var bmw = new Bmw(1);
var bmw1 = new Bmw(2);
console.log(bmw.wheel) //wheel

bmw1.arr.push(3);
console.log(bmw.arr) //[1,2]
console.log(bmw1.arr); //[1,2,3]
bmw.drive();  ////车速:1
bmw1.drive(); //车速:2

核心:组合继承就是把构造函数继承和原型链继承组合到一起。

   构造函数继承的缺点就是函数,把函数放到父函数的原型链上就可以了。

缺点:父函数的构造函数被调用了2次。子类和子类的原型链上有相同的属性。如下图:

arr和wheel属性重复,有些内存浪费。

 寄生组合继承(最佳)

function excess(obj){       //核心
    var F = function(){};
    F.prototype = obj;
    return new F();
}
function Car(){
    this.wheel = "wheel";
    this.arr = [1,2];
}
Car.prototype.drive = function(){          //核心
    console.log("车速:"+this.speed);
}
function Bmw(speed){
    this.speed = speed;
    Car.call(this);    //核心
};
Bmw.prototype = excess(Car.prototype);   //核心
Bmw.constructor = Bmw;  //核心
var bmw = new Bmw(1);
var bmw1 = new Bmw(2);
console.log(bmw.wheel) //wheel

bmw1.arr.push(3);
console.log(bmw.arr) //[1,2]
console.log(bmw1.arr); //[1,2,3]
bmw.drive();  ////车速:1
bmw1.drive(); //车速:2

 

核心:将父类的原型传入函数excess来获得一个新的原型(剪掉了多余的属性),将新的原型附给子类的原型。

   没有什么缺点了。

posted on 2017-04-13 18:12  热爱游戏享受生活  阅读(148)  评论(0编辑  收藏  举报