带你看懂JavaScript的继承(七) 寄生式继承

在原型模式之后(注意,是原型模式),我们讲了借用构造函数继承,对,又叫做经典继承。请大家回忆一下。

在上一期讲完原型式继承之后,本期同样的,我们继续来拓展它。寄生式继承,也是由克罗克福德发明并推广的。大家真的应该google一下这个人,老古语,吃水不忘挖井人,毕竟善良的心,才能写出好的代码,而且我们也应该对我们的代码心存敬畏。一个字母干瘫了半个互联网的故事刚过去不久,有趣的是,如果你还记得Amazon S3服务宕机之前,gitlab的一名工程师错误的在主服务器上删除了300G的数据导致其长时间瘫痪的事故(这个哥们只用了一条简单的命令,只是执行了不到两秒钟哦)。gitlab的其中一个主要备份方式就是每天向Amazon S3服务器上传一个从来没有成功过的快照,而他们并不知道。所以永远都应该保持对代码的敬畏,错误的不是代码,而是人本身。哈哈,一不小心写跑偏了,大家见谅,突然想起了大学算法老师讲过的一句,哲学是一切科学的基础,你的代码也是哲学。是不是觉得逼格马上就来了。

好了回归主题。寄生式继承的寄生构造函数和工厂模式类似(相信有很多人没听过啊,这是javascript关于对象的知识,不懂的话我们下一个系列就聊聊javascript的对象)。直白的说,就是我们会创建一个只是用于封装继承过程的方法,该方法的内部以某种方式来增强对象,最后我们返回这个增强了的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
function object(o){  
function F(){}
F.prototype = o;
return new F();
}

function createAnother(original){
var clone = object(original) //创建一个新对象
clone.sayHi = function(){ //增强对象
alert("Hi!");
}
return clone; //返回对象
}

很简单吧,是不是我们就封装了一个继承对象并增强对象的过程。你可以如下使用这个过程。

1
2
3
4
5
6
7
var person ={  
name: "shuai";
family: ["parents"];
}

var anotherPerson = createAnother(person);
anotherPerson.sayHi(); //"Hi!"

我们返回了anotherPerson,它具有person的所有属性和方法,并且还有自己的sayHi()方法。

当你主要关心的是对象而不是自定义类型或者是构造函数的情况下,寄生式继承就帮你的大忙了。Object函数不是必须得,你可以使用任何能够返回新对象的方法。

缺点当然显而易见,是什么?想想借用构造函数的缺点,一样的,函数不能复用的,会降低效率。

这期我们就讲到这里,下一期我们会结合组合继承的特点,来讲一个相对来说更完美的一种继承。当然,完美只是相对的。