与所有派生子

时间:2016-02-29 22:15:43

标签: javascript inheritance prototype

假设有一个父类Shape和一个子类Rectangle。我想从子类中重用父类属性的值。

我可以不在子类中重新初始化它(使用call或apply)吗?

我希望所有子对象都使用相同的父属性值。



//Parent
function Shape(ctx) {
  this.context = ctx;
}
Shape.prototype.getContext = function() { return this.context; };

//Child - rectangle inherits from shape
function Rectangle(x,y,w,h) {
  this.x = x;
  this.y = y;
  this.w = w;
  this.h = h;
}
//setup inheritance
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

Rectangle.prototype.draw = function() {
  //want to use inherited context here
  return this.context;
}

//create and run
var shape = new Shape("value");
var rectangle = new Rectangle(0,0,100,100);

//returns "value"
console.log( shape.getContext() );
//returns undefined - needing "value"
console.log( rectangle.draw() );




编辑 - 在下面的回复后,我认为这是我需要的。由于矩形实例不是从形状实例继承"值"分配给形状不会传递给矩形。如何将其指定为Shape内部的默认值,然后在Rectangle构造函数中调用Shape构造函数。这允许我对所有子对象共享相同的上下文值吗?

方面问题,setter不会影响Shape儿童。所以我正在努力。



//Parent
function Shape() {
  this.context = "value";
}
Shape.prototype.getContext = function() { return this.context; };
Shape.prototype.setContext = function(x) { this.context = x; };

//Child - rectangle inherits from shape
function Rectangle(x,y,w,h) {
  Shape.call(this);
  this.x = x;
  this.y = y;
  this.w = w;
  this.h = h;
}
//setup inheritance
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

Rectangle.prototype.draw = function() {
  //want to use inherited context here
  return this.context;
}

//create and run
var rectangle = new Rectangle(0,0,100,100);
//returns "value"
console.log( rectangle.draw() );




编辑 - 感谢回复,我认为以下是完成我最初尝试做的事情。 Shape父级以默认上下文值开头。 Shape构造函数现在也接受一个参数,以防子类在最初调用时想要更改它。然后,每个子类都有一个getter和setter以及上下文,但除非更改,否则它将始终默认为初始Parent值。在调查之后,Shape开始感觉像是一个抽象类或接口,但这与我最初要求的内容无关。

//Parent
function Shape(ctx) {
  this.context = (typeof ctx === "undefined") ? "default" : ctx;
}
Shape.prototype.getContext = function() { return this.context; };
Shape.prototype.setContext = function(x) { this.context = x; };

//Child - rectangle inherits from shape
function Rectangle(x,y,w,h) {
  //calls parent constructor
  Shape.call(this);
  this.x = x;
  this.y = y;
  this.w = w;
  this.h = h;
}
//setup inheritance
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
//getter and setter - context defaults to parent value, but can be changed
Rectangle.prototype.getContext = function() { return this.context; };
Rectangle.prototype.setContext = function(x) { this.context = x; };
//other rectangle methods
Rectangle.prototype.draw = function() {
  return "doing something with " + this.context;
}

//create and run
var rectangle = new Rectangle(0,0,100,100);
//starts with Parent "default"
console.log( rectangle.getContext() );
//changes and uses different context
rectangle.setContext("different context");
console.log( rectangle.draw() );

2 个答案:

答案 0 :(得分:0)

执行此操作设置矩形时,返回值为undefined

//create and run
var shape = new Shape("value");
var rectangle = new Rectangle(0,0,100,100);

因为您实际上shaperectangle相关联。你只做了两个单独的Shape和Rectangle实例,除了共享某些结构之外没有任何关系。

有可能解决此问题。创建一个新的Shape,在定义原型时预先为值设定值。

//Use predefined Shape
var shape = new Shape("value");
Rectangle.prototype = shape;

现在,当使用先前显示的draw调用时,将返回value并将其记录到控制台。

在我看来,这不是一个完整的场景,因为虽然您已经为上下文定义了一个getter,但是可能存在您希望更改它的场景。我还建议为上下文实现一个setter,这样你就可以注入不同的内容。

答案 1 :(得分:0)

  

我可以不在子类中重新初始化它(使用call或apply)吗?

不,没有办法调用你的超级构造函数。

请注意,这不是 re - 初始化属性,调用正在创建并初始化属性

  

我想在子类中重用父类属性的值。

这并没有多大意义。该属性是实例的一部分,而不是类的一部分。如果您有多个子节点,则没有父类的实例,只有子实例。如果你真的在创建父类的实例(就像在你的示例代码中那样),那么这是一个单独的对象,与其他实例无关 - 大多数情况下,子对象不以任何方式从该父实例派生