在JavaScript中设置子类的.prototype

时间:2012-05-23 23:30:50

标签: javascript oop

鉴于这段代码:

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对象(具有自己的ab属性)对我来说似乎很奇怪,只是作为{{1}的原型}。

这也有效:

SubClass

但它通过引用传递// anti-pattern SubClass.prototype = SuperClass.prototype; 对象,因此您添加到SuperClass.prototype的任何内容也会添加到SubClass.prototype,因为它们是同一个对象。在大多数情况下,这不是预期的行为。

问题:有没有办法实现正确的原型设计而不创建SuperClass.prototype的实例作为SuperClass的基本原型?

2 个答案:

答案 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();