道格拉斯丶克罗克福德有一个观点是:借助原型prototype可以根据已有的对象创建一个新的对象,同时不必创建新的自定义对象类型。代码如下:
//原型式继承
function inheritObject(o){
//声明一个过渡函数对象
function F(){}
//过渡对象的原型继承父对象
F.prototype = o;
//返回过渡对象的一个实例,该实例的原型继承了父对象
return new F();
}
这种方式和类式继承有些像,它是对类式继承的一个封装,其中的过渡对象就相当于类式继承的子类,只不过在原型式中作为一个过渡对象出现的,目的是为了创建要返回的新的实例化对象。
由于F过渡类的构造函数中无内容,所以开销比较小,使用起来比较方便。当然我们还可以把F过渡类缓存起来,不必每次创建一个新的过渡类F。随着这种思想的加深,Object.create()这种形式就应运而生。
var book = {
name:"js book",
alikebook:["css book","html book"]
};
var newBook = inheritObject(book);
newBook.name = "ajax book";
newBook.alikebook.push("xml book");
var otherBook = inheritObject(book);
otherBook.name = "flash book";
otherBook.alikebook.push("as book");
console.log(newBook.name); //ajax book
console.log(newBook.alikebook);//["css book","html book","xml book","as book"]
console.log(otherBook.name);//flash book
console.log(otherBook.alikebook);//["css book","html book","xml book","as book"]
console.log(book.name);//js book
console.log(book.alikebook);//["css book","html book","xml book","as book"]
跟类式继承一样,父类对象book中的值类型的属性被复制,引用类型的属性被共用。
然而,道格拉斯丶克罗克福德推广的继承并不只这一种,他在此基础上做了一些增强而推出一种寄生式继承。
//寄生式继承
//声明基对象
var book = {
name:"js book",
alikebook:["css book","html book"]
};
function createBook(obj){
//通过原型继承方式创建新对象
var o = new inheritObject(obj);
//拓展新对象
o.getName = function(){
console.log(name);
};
//返回拓展后的新对象
return o;
}
寄生式继承就是对原型继承的第二次封装,并且在这第二次封装过程中对继承的对象进行了拓展,这样新创建的对象不仅仅有父类中的属性和方法而且还添加新的属性和方法。
(ps:参考js设计模式)