javascript 理解继承

一.继承-通过原型实现继承

function Father() {
    this.FatherSkin = "yellow";
};
Father.prototype.getFatherSkin = function () {
    return this.FatherSkin;
};
function Son() {
    this.SonSkin = "black";
};
// 继承: 子类原型等于父类的实例。
Son.prototype = new Father();
// 添加新的方法。
Son.prototype.getSonSkin = function () {
    return this.SonSkin;
}
// 重写父类方法,重写父类方法并不会影响父类实例方法。
Son.prototype.getFatherSkin = function () {
    return 'restSkin';
}
var son1 = new Son();
var father1 = new Father();

// console.log(son1 instanceof Son); // true
// console.log(son1 instanceof Father); // true
// console.log(son1.getFatherSkin); // 'restSkin'
// console.log(father1.getFatherSkin); // 'yellow'

/*
原型实现继承的问题:
1.如果父类的构造函数中有引用类型的属性,那么子类继承后的实例属性会共享。
2.子类不能向父类的构造函数中传递参数。
 */
function Fruits() {
    this.info = ['size', 'width'];
};
function Apple() {

};

Apple.prototype = new Fruits();

var apple1 = new Apple();
var apple2 = new Apple();
apple1.info.push('height');
// apple1实例修改属性,会影响apple2实例。
// console.log(apple1.info); // ['size', 'width', 'height']
// console.log(apple2.info); // ['size', 'width', 'height']

二.继承-借用构造函数实现向父类传递参数

function Pi(age) {
    this.age = age;
};

function Si() {
    Pi.call(this, 20);
    this.name = 'acfun';
};

var si1 = new Si();
// console.log(si1); // {age: 20, name: "acfun"}

/*
借用构造函数的问题:
1.方法都在构造函数中,实例方法重载了。
2.因为没有把父类的实例赋给子类的原型,所以在父类原型中定义的方法,子类无法使用。
 */

三.继承-组合继承

function Phone(soc) {
    this.soc = soc;
    this.color = ['red', 'blue'];
}
Phone.prototype.getInfo = function () {
    return `${this.soc},${this.color}`
}
function XiaoMi(soc, tag) {
    Phone.call(this, soc);
    this.tag = tag;
}
XiaoMi.prototype = new Phone();
XiaoMi.prototype.constructor = XiaoMi;
XiaoMi.prototype.getTag = function () {
    return this.tag;
};

var mi1 = new XiaoMi('855', 'xm');
var mi2 = new XiaoMi('835', 'xm');
mi1.color.push('purple');
// console.log(mi1.getInfo()); // "855,red,blue,purple"
// console.log(mi2.getInfo()); // "855,red,blue"

/*
优点:
1,通过构造函数修改了this指向,this指向了实例对象,所以父类构造函数上的属性即便是引用类型,也不存在共享的情况。
 */

插曲-原型式继承

// 浅复制
function createObj(o) {
    function F() { };
    F.prototype = o;
    return new F();
};
var test1 = {
    name: 'test',
    opt: [1, 2, 3]
}

var test2 = createObj(test1); // 相等 var test2 = Object.create(test1);
test2.opt.push(4);
// console.log(test2.opt); //  [1, 2, 3, 4]
// console.log(test1.opt); //  [1, 2, 3, 4]

四. 继承-寄生组合式继承

// 最理想的继承方式
var inheritPrototype = function (subType, superType) {
    var prototype = superType.prototype;
    prototype.constructor = subType;
    subType.prototype = prototype;
}

function Water(ml) {
    this.ml = ml;
    this.color = ['red', 'blue'];
}
Water.prototype.getInfo = function () {
    return `${this.ml},${this.color}`
}
function MaiDong(ml, tag) {
    Water.call(this, ml);
    this.tag = tag;
}
inheritPrototype(MaiDong, Water);

MaiDong.prototype.getTag = function () {
    return this.tag;
};

var mai1 = new MaiDong('300', 'md');
var mai2 = new MaiDong('600', 'md');
mai1.color.push('purple');
// console.log(mai1.color); //  ["red", "blue", "purple"]
// console.log(mai2.color); //  ["red", "blue" ]

es6继承

class A {

}
class B extends A {
    constructor() {
        super()
    }
}

三大步 go on

posted @ 2019-04-17 17:55  hid3onbush  阅读(245)  评论(0编辑  收藏  举报