Javascript 寄生组合式继承
接触了好几种继承模式了,在前一篇文章,我们就说到了一些继承方法,本以为组合是最好的,结果没想到还有。
故事从原型式继承说起:
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)
我感觉js里要继承核心还是`prototype`, 也就是原型链继承,或者在部分平台下直接操作`__proto__`可以简化一些 之前那篇*Javascript call()与apply()*里的继承方式有点问题,`SubType.prototype = new SuperType();`直接调用了父类的构造函数,这样会导致原先的*实例变量*变为*类变量*,这篇文章中用的方法才是通常js里的继承
一般来说,`prototype`里都是方法,而别的类型的属性(`Object`,`Array`,`String`,`Number`,`RegExp`等)通常在构造函数中初始化。 虽然我好像没有见过不是这样做的js oop,但是还是感觉不够好。 可能是js的oop确实比较弱,有些问题比如,怎么实现类变量,要显式的调用父类构造函数,调用被覆盖的父类方法要显式的写出父类名(例如`SUPERCLASSNAME.prototype.FUN.call(this)`),这点有点类似c++, 还有就是封装性不足。