繁体   English   中英

Javascript:允许基类中的“虚拟”函数创建子类的实例

[英]Javascript: Allowing “virtual” function in base class to create instance of subclass

我有以下要使用的对象模型-一直在模仿克隆位! 这可能吗? 如果没有对它进行硬编码,我似乎无法从基类中访问SubClass构造函数。

该代码用于队列的任意操作,这些操作均共享许多通用功能; 新操作将创建为子类,这些子类仅覆盖action()方法以实现特定于操作的功能。

是否可以在不重写每个子类中的clone()方法的情况下实现?

/*
Application specific subclass:
*/
function SubClass_Operation1()
{
  BaseOperationClass.apply(this, arguments); // Call inherited constructor

  this.action = function()
  {
    this.manager.addToQueue(this.clone({changeValue:1}));
    this.manager.addToQueue(this.clone({changeValue:2}));
    this.manager.addToQueue(this.clone({changeValue:3}));
  }
}
SubClass.prototype = new BaseOperationClass;

// More of these defined for each operation
...

/*
Base class containing all common functionality
*/
function BaseOperationClass(manager)
{
  this.manager = manager;

  // Placeholder for virtual action() function
  this.action = function()
  {
  }

  this.clone = function(mods)
  {
    var res = ?????? // Should create exact copy of current SubClass

    res.applyModifications(mods);
  }

  this.applyModifications(mods)
  {
    ...
  }

  // Lots of common functionality 
  ...
}

为了在您的.clone()方法中访问构造函数而不必对其进行硬编码,通常的解决方案是使用.constructor属性,每个对象都可以在自己的原型上设置该属性。 叶对象定义将在构造函数属性上具有重写,并将成为要调用的所需构造函数。 就像您已经知道的那样,使用此方法克隆对象需要一些有关必须发送给构造函数的参数的知识。

在此示例中,构造函数不使用任何参数。 然后,它要求每个对象都支持一个.init方法,该方法接受要从其克隆对象的对象,因此每个类负责从原始对象初始化新的克隆。

这是正在运行的代码段中的一个示例:

 function Base() { this.type = "base"; } Base.prototype = { clone: function () { var c = new this.constructor(); // let clone initialize itself from the original c.init(this); return c; }, setName: function(name) { this.name = name; }, init: function(obj) { // copy over name instance data this.name = obj.name; } } // set .constructor property for use with .clone() Base.prototype.constructor = Base; function Derived() { Base.call(this); this.type = "derived"; } // inherit from Base Derived.prototype = Object.create(Base.prototype); Derived.prototype.setOccupation = function(occupation) { this.occupation = occupation; } Derived.prototype.init = function(obj) { // let base object init itself Base.prototype.init.call(this, obj); // copy over our own instance data this.occupation = obj.occupation; } // set .constructor property for use with .clone() Derived.prototype.constructor = Derived; var x = new Derived(); x.setName("Bob"); x.setOccupation("Engineer"); var xx = x.clone(); var y = new Base(); y.setName("Alice"); var yy = y.clone(); log(x !== xx) log(x); log(xx); log(y); log(yy) // function just for output in snippet function log(a) { var div = document.createElement("div"); if (typeof a === "object") { a = JSON.stringify(a); } div.innerHTML = a; document.body.appendChild(div); } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM