javaScript继承

129 阅读2分钟

借用构造函数

这是经典的继承方式。

栗子:

function Father() {
    this.colors = ["red","green","blue"];
}
function Son() {
	Father.call(this);  
}
var instance1 = new Son();
alert( Father.prototype.isPrototypeOf(instance1))  //false
instance1.colors.push("black");
console.log(instance1.colors);   //"red","green","blue","black"

var instance2 = new Son();
console.log(instance2.colors);  //"red","green","blue" 可见引用类型值是独立的

只是借用了Father构造函数,但并没有改变_proto_指针的指向,Father函数并不在instance1的原型链上。

这个继承方法解决了两个问题:

  1. 保证了引用类型属性值是独立的,不再被所有实例共享;
  2. 子类型创建时也能向父类传递参数。

组合继承

上一种方法只是调用了Father构造函数,但是没办法调用Father.prototype上的方法。

组合继承将原型链和借用构造函数继承结合在一起,既能借用构造函数,也能继承原型链上的方法。

栗子:

    function Father1(name) {                  //使用借用构造函数方法继承
    	this.colors = ["red","green","blue"]; 
    	this.name = name; 
    } 
    Father1.prototype.sayName = function() {  //借用原型链继承此方法
    	alert(this.name); 
    };

    function Son1(name,age) {
    	Father1.call(this,name);
    	this.age = age; 
    }

    Son1.prototype = new Father1();
    Son1.prototype.sayAge = function() {
    	alert(this.age);
    };

    var instance3 = new Son1("peter",15);
    instance3.colors.push("black");
    console.log(instance3.colors)   //"red","green","blue","black"
    instance3.sayName();    //"peter"
    instance3.sayAge();     //15
    
    var instance4 = new Son("liHua",20);
    console.log(instance4.colors);  //"red","green","blue"
    instance3.sayName();    //"liHua"
    instance3.sayAge();     //20

这是Javascript最常用的继承方式,而且, instanceof 和 isPrototypeOf( )也能用于识别基于组合继承创建的对象.

原型继承

var person = {
    name : ["liHua","wangHua","baiXue"]
};
var anotherPerson = Object.create(person);
anotherPerson.name.push("huTai");
console.log(anotherPerson.name);          //"liHua","wangHua","baiXue","huTai"
console.log(person.name);           //"liHua","wangHua","baiXue","huTai"

将person对象传入Object函数中,得到一个新对象,这个新对象以person为原型,则原型中包含的引用类型值属性被共享了,既person.name不仅被person所有,而且也被anotherPerson共享。

寄生式继承

创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回被增强的对象。

var clonePerson = function(original) {
    var clone = Object(original);  //通过Object函数创建一个以接收对象为原型的新对象
    clone.sayHi = function() {  //增强这个对象
        alert("Hi");
    };
    return clone;  //返回对象
};

寄生组合式继承

基本思路: 不必为了指定子类型的原型而调用超类型的构造函数

function extend(subClass,superClass){
    var prototype = object(superClass.prototype);//创建对象
    prototype.constructor = subClass;//增强对象
    subClass.prototype = prototype;//指定对象
}

下面我们来看下extend的另一种更为有效的扩展.

function extend(subClass, superClass) {
    var F = function() {};
    F.prototype = superClass.prototype;
    subClass.prototype = new F(); 
    subClass.prototype.constructor = subClass;

    subClass.superclass = superClass.prototype;
    if(superClass.prototype.constructor == Object.prototype.constructor) {
        superClass.prototype.constructor = superClass;
    }
}

补充

这篇笔记里用到的栗子出自这里