我们都熟悉以下polyfill来在JavaScript中创建对象:
function inherit(C, P) {
var F = function () {};
F.prototype = P.prototype;
C.prototype = new F();
}
这样做的一个缺点是您将无法访问父母自己的成员。子实例只能访问原型链。
所以我认为最好的继承解决方案如下:
var inherit = (function () {
var F = function () {};
return function (C, P) {
F.prototype = P.prototype;
C.prototype = new F();
C.prototype.constructor = C;
}
}());
function Parent(a){
this.a = a;
}
Parent.prototype.a_proto = function(){return "a_proto";}
function Child(a,b){
Parent.apply(this,[a]);
this.b = b;
}
inherit(Child, Parent);
var c = new Child("a","b");
console.log(c.a); // a
console.log(c.b); // b
console.log(c.a_proto()); // a_proto
delete c.a;
console.log(c.a); // undefined
我之所以喜欢上述解决方案,是因为首先使用apply
函数将父级自己的成员复制到子级自己的成员,因此允许父级自己的成员真正继承。其次,孩子也有一个到原型链的链接,因此可以继承父级的原型属性......由于我们使用代理,孩子不能修改父级的原型。
我还在 JavaScript Patterns 一书中介绍了uber方法的概念。基本上,在超级方法中,作者说我们“添加对原始父母的引用”。这就像访问其他语言的超类一样,偶尔可以使用。“这是实现:
function inherit(C, P) {
var F = function () {};
F.prototype = P.prototype;
C.prototype = new F();
C.uber = P.prototype;
}
我不知道如何添加对原始父级的引用是好的。现在,孩子能够修改父母的原型,这是一件坏事。这个人在谈论什么,我们现在可以像其他语言一样访问超类?我想使用apply
并且原型链已经可以访问超类。参考父母的原型真的有什么好处吗?