JavaScript继承😅

继承

原型链

原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针

原型中有构造函数,指向类

组合继承

function SuperType(name) {
    this.name = name;
    this.color = ["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指向的是SuperType,需要改回来
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function (){
    alert(this.age);
};

组合继承避免了原型链和借用构造函数的缺点,融合了他们的优点,成为JavaScript中最常用的继承模式

原型继承模式

//原型式继承
function object(o) {
    function F() {
    }

    F.prototype = o;
    return new F();
}

var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

alert(person.friends);

ECMAScript5新增Object.create()方法规范化了原型式继承。

//ECMAScript5新增Object.create()方法规范化了原型式继承。
var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = Object.create(person)

Object.create()方法的第二个参数与Object.defineProperties()方法的第二个参数相同:每个属性都是通过自己的描述符定义的。以这种方式指定的任何属性都会覆盖原型对象上相同属性(只是覆盖不是失效和下面有区别)。

var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = Object.create(person,{
    name: {
        value: "Greg"
    }
});
alert(person.name);//"Greg"

PS​😷: 原型中使用字面量添加方法会导致,原来的原型失效

SubType.prototype = new SuperType();
//下面代码会导致上面的失效
SubType.prototype = {
	getSubValue: function(){
		return this.subProperty;
	},
	otherMethod: function(){
		return false;
	}
}

寄生式模式

和工厂模式类似,仅创建一个封装继承过程的函数

//寄生式模式
function createAnother(original){
    var clone = object(original);
    clone.sayHi = function(){
        alert("hi");
    };
    return clone;
}
var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person)
anotherPerson.sayHi();

寄生组合式继承

组合继承是最常用的,但是他的不足是无论什么情况下都要调用两次超类构造函数:一次是在创建子类型原型的时候,一次是在子类型构造函数内部;

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指向的是SuperType,需要改回来
SubType.prototype.constructor = SubType; 
// 第一次
// 上面两句话 可以改成下面的模式
SubType.prototype.sayAge = function (){
    alert(this.age);
};

寄生组合式继承的基本模式如下

//寄生组合模式
function inheritPrototype(subType, superType){
    var prototype = object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}

SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType; 
// 上面两句话 可以改成下面的模式
inheritPrototype(SubType, SuperType)
posted @ 2021-09-26 17:05  _Salvatore  阅读(28)  评论(0)    收藏  举报