2

我有一个非常独特的问题,我不确定我应该如何解决它,是否有解决它的最佳方法,和/或这是否是设计模式缺陷。

问的原因是我相信我不应该为相同的功能重写函数。以下面的示例代码为例;

 function Div(config) {

     var config = config || {};
     this.element = document.createElement("div");
     this.setSize(config.width || 0, config.height || 0);
 };

 Div.prototype.setSize = function(width, height) {

     this.setWidth(width);
     this.setHeight(height);
 };

 Div.prototype.setWidth = function(width) {

     this.element.style.width = width + "px";
 };

 Div.prototype.setHeight = function(height) {

     this.element.style.height = height + "px";
 };

 Div.prototype.appendTo = function(element) {

     element.appendChild(this.element);
 };

你可以看到上面的代码允许我创建div标签。我可以轻松创建 html div,设置它们的大小并将它们附加到其他元素。

我还有一个Overlay需要继承的对象Div。起初我决定设置DivOverlay的原型。

 function Overlay(config) {

      var config = config || {};
      this.setSize(config.width, config.height);
 };

 Overlay.prototype = new Div();

这工作得很好,但是问题出现了,因为Overlay它本质上是Div带有一些附加功能的。由于Overlay对象Div的原型是它只指向一个 div 元素,而每个实例都Overlay应该有自己的 div 元素。

然后我决定做Div一个财产Overlay;

 function Overlay(config) {

     var config = config || {};
     this.div = new Div(config);
 };

这也可以正常工作,但是现在在创建实例时,Overlay我必须像这样使用它;

 var overlay = new Overlay();
 overlay.div.setSize(100, 100);

而不是;

 var overlay = new Overlay();
 overlay.setSize(100, 100);

为了解决这个问题,我创建了新的原型函数Overlay来简化使用它,Overlay因为它现在看起来像这样;

 function Overlay(config) {

     var config = config || {};
     this.div = new Div(config);
 };

 Overlay.prototype.setSize = function(width, height) {

     this.div.setWidth(width);
     this.div.setHeight(height);
 };

 Overlay.prototype.setWidth = function(width) {

     this.div.setWidth(width);
 };

 Overlay.prototype.setHeight = function(height) {

     this.div.setHeight(height);
 };

 Overlay.prototype.appendTo = function(element) {

     this.div.appendTo(element);
 };

像这样创建Overlay正是我想要的功能Overlay,但对我来说这似乎是非常错误的,因为我实际上是为了易于使用而编写函数,并且Div随着大小可维护性的增长成为真正的痛苦。

虽然设置DivOverlay' 的原型似乎是正确的做事方式,但在我的情况下,它显然不是所有实例Overlay都绑定到同一个 div 元素。

我怎样才能同时创建一个Div对象和一个Overlay对象,在哪里Overlay有它自己的实例,Div但也会继承Div它的原型的所有功能?是否有我应该使用的模式来解决我面临的这个问题?

我真的不知道从哪里开始,但我想我很确定我现在这样做的方式不是正确的方式!

感谢您花时间阅读我的问题。

4

1 回答 1

2

要使您的代码工作并允许您删除所有这些添加的功能,请将以下内容添加到您的Overlay构造函数中:

Div.call(this);

Overlay并在声明构造函数后添加这一行:

Overlay.prototype = Object.create(Div.prototype);

解释: 这里是我们正在做的更详细的细分。首先,定义Div构造函数并赋予其原型一些功能:

function Div() {
    this.propA = true;
}
Div.prototype.sayMyProp = function(){
   alert(this.propA);   
};

定义Overlay构造函数:

function Overlay() {
    Div.call(this);  // This gives any Overlay object the properties of Div
    // Define some properties specific to Overlay
    this.propB = true;
}

Overlay为继承自的原型创建一个新Div原型:

Overlay.prototype = Object.create(Div.prototype);

请注意,这不会复制on 的属性Div.prototypeOverlay.prototype它只是创建一个Overlay.prototype具有对 的“父”引用的对象Div.prototype。没有它自己的属性(尽管如果我们没有覆盖它,Overlay.prototype它会有一个属性)。constructor接下来,通过创建两个实例来测试我们的结构Overlay

var o1 = new Overlay();
var o2 = new Overlay();

o1.propA = false;  // Does not change o2.propA because it is an "own"
                   // property of Overlay instances

他们可以访问 Div 原型上的函数:

o1.sayMyProp();    // FALSE
o2.sayMyProp();    // TRUE, so they are not sharing the same propA

小提琴: 这是一个小提琴

于 2013-05-15T16:15:27.530 回答