鉴于这段代码:
var SuperClass = function(a, b) {
this.a = a;
this.b = b;
};
SuperClass.prototype.getA = function() {
return this.a;
};
var SubClass = function(a, b, c) {
SuperClass.call(this, a, b);
this.c = c;
};
为了启动SubClass
原型,大多数建议似乎如下:
SubClass.prototype = new SuperClass();
创建(实例化)新的SuperClass
对象(具有自己的a
和b
属性)对我来说似乎很奇怪,只是作为{{1}的原型}。
这也有效:
SubClass
但它通过引用传递// anti-pattern
SubClass.prototype = SuperClass.prototype;
对象,因此您添加到SuperClass.prototype
的任何内容也会添加到SubClass.prototype
,因为它们是同一个对象。在大多数情况下,这不是预期的行为。
问题:有没有办法实现正确的原型设计而不创建SuperClass.prototype
的实例作为SuperClass
的基本原型?
答案 0 :(得分:5)
在现代浏览器下:
SubClass.prototype = Object.create( SuperClass.prototype );
这使您可以使用已定义的__proto__
创建一个对象,而无需调用父类的'constructor'方法。有关更多详细信息,请阅读Object.create
(包括旧浏览器的polyfill实现)。
见过:
function Foo(){ console.log("AHHH!"); }
Foo.prototype.foo = 42;
function Bar(){}
Bar.prototype = Object.create(Foo.prototype); // Note: no "AHHH!" shown
Bar.prototype.bar = 17;
// Showing that multi-level inheritance works
var b = new Bar;
console.log(b.foo,b.bar); //-> 42, 17
// Showing that the child does not corrupt the parent
var f = new Foo; //-> "AHHH!"
console.log(f.foo,f.bar); //-> 42, undefined
// Showing that the inheritance is "live"
Foo.prototype.jim = "jam";
console.log(b.jim); //-> "jam"
答案 1 :(得分:0)
旧版浏览器的Polyfill实现
// Create a new instance based on existing object
function object(o) {
function F() {};
F.prototype = o;
return new F();
}
function inherit(subClass, superClass) {
var prototype = object(superClass.prototype);
prototype.constructor = subClass;
subClass.prototype = prototype;
}
虽然传递superClass.prototype导致F.prototype = superClass.prototype
,但是当对象函数返回时,不再访问F函数。结果,您无法获取和更改F.prototype。
示例:
function SuperClass() {};
function SubClass() {};
SuperClass.prototype.say = function() {console.log('super');};
var instance = object(SuperClass.prototype); //instance.__proto__ === SuperClass.prototype
instance.say();