CodeSky 代码之空

随手记录自己的学习过程

Javascript 寄生组合式继承

2014-07-23 13:34分类: JavaScript评论: 2

接触了好几种继承模式了,在前一篇文章,我们就说到了一些继承方法,本以为组合是最好的,结果没想到还有。

故事从原型式继承说起:

1function object(o) {
2    function F(){}
3    F.prototype = o;
4    return new F();
5}
6
7var person = {
8    name: "Nicholas",
9    friends: ["Shelby", "Court", "Van"]
10};
11
12var anotherPerson = object(person);
13anotherPerson.name = "Greg";
14anotherPerson.friends.push("Rob");
15
16var yetAnotherPerson = object(person);
17yetAnotherPerson.name = "Linda";
18yetAnotherPerson.friends.push("Barbie");
19
20console.log(person.friends);
21

原型式继承似乎略像prototype的情况,输出为[ 'Shelby', 'Court', 'Van', 'Rob', 'Barbie' ]

之后我们可以用自带的Object.create()来代替定义的函数。

寄生式继承也是运用了这一特点

1function createAnother(original) {
2    var clone = Object.create(original);
3    clone.sayHi = function() {
4        console.log("hi");
5    };
6    return clone;
7}
8
9var person = {
10    name: "Nicholas",
11    friends: ["Shelby", "Court", "Van"]
12};
13
14var anotherPerson = createAnother(person);
15anotherPerson.sayHi();
16

不懂的是为什么在这里定义的sayHi就无法共享给person。

而寄生组合式继承目前似乎被称为最高效的方式(-_-其实我也没明白)

1function inheritPrototype(subType, superType) {
2    var prototype = Object.create(superType.prototype);
3    prototype.constructor = subType;
4    subType.prototype = prototype;
5}
6
7function SuperType(name) {
8    this.name = name;
9    this.color = ["red", "blue", "green"];
10}
11
12SuperType.prototype.sayName = function() {
13    console.log(this.name);
14};
15
16function SubType(name, age) {
17    SuperType.call(this, name);
18
19    this.age = age;
20}
21
22inheritPrototype(SubType, SuperType);
23
24SubType.prototype.sayAge = function() {
25    console.log(this.age);
26};
27

评论 (1)

Horizon2014年12月27日 21:39

我感觉js里要继承核心还是`prototype`, 也就是原型链继承,或者在部分平台下直接操作`__proto__`可以简化一些 之前那篇*Javascript call()与apply()*里的继承方式有点问题,`SubType.prototype = new SuperType();`直接调用了父类的构造函数,这样会导致原先的*实例变量*变为*类变量*,这篇文章中用的方法才是通常js里的继承

Horizon2014年12月27日 22:14

一般来说,`prototype`里都是方法,而别的类型的属性(`Object`,`Array`,`String`,`Number`,`RegExp`等)通常在构造函数中初始化。 虽然我好像没有见过不是这样做的js oop,但是还是感觉不够好。 可能是js的oop确实比较弱,有些问题比如,怎么实现类变量,要显式的调用父类构造函数,调用被覆盖的父类方法要显式的写出父类名(例如`SUPERCLASSNAME.prototype.FUN.call(this)`),这点有点类似c++, 还有就是封装性不足。