子类工厂缺少原型 - Javascript

Subclass factory missing prototype - Javascript

我正在尝试创建一个工厂函数,它接受一个超类和一个函数作为参数,returns一个子类的构造函数,它覆盖 add() 方法并将过滤器应用于 add() 方法。

我遇到的问题是,当我使用此构造函数创建此子类对象并调用 add() 时,无法识别 add() 方法。

如果有帮助,我正在尝试使用类似于 Javascript - David Flanagan 的权威指南中的第 9.7.2 节的技术。

感谢任何帮助,谢谢。

function subclassFactory(superclass,func){
     var constructor = function(){
        superclass.apply(this,arguments);    

        var proto = constructor.prototype 
                  = Object.create(superclass.prototype);
        proto.constructor = constructor; 

        proto.add = function(){
             if(!func(arguments)) 
             {
              return superclass.prototype.add.apply(this,arguments);
             } 
         }
     }

     return constructor;
  }

如果您第一次调用 subclassPrototype 并且 superclass 变量在其原型链中没有 add 方法,则会发生这种情况:

var parent = subclassFactory(function () {}, function(args) { ... }),
    child = subclassFactory(parent, function(args) { ... }),
    childInstance = new child();

child.add(...); // throws an exception

解决方案:

  1. 调用前先检查add方法

  2. 始终传入一个超级 class 对象,该对象在其原型链的某处定义 add

  3. 检查 superClass 原型中是否有 add 方法,如果不存在则抛出错误

  4. 如果"add"方法在superclass上不存在,默认为空函数

不要在构造函数中修改原型。

并且请(根据经验)永远不要将参数对象传递给任何函数。 您希望避免传递参数-反对另一个功能。 它阻止了通过底层 JS 引擎进行的优化。请改用展开运算符 (ES6 Rest parameters @ MDN) 或手动将参数复制到数组中。

function subclassFactory(superclass, func){
    var constructor = function(/*...args*/){
        //for(var i=arguments.length,args=Array(i);i--;)args[i]=arguments[i];
        //return superclass.apply(this, args);
        return superclass.apply(this, arguments);
    }

    constructor.prototype = Object.create(superclass.prototype, { 
        constructor: { 
            configurable: true, 
            value: constructor 
        },
        add: { 
            value: function(/*...args*/){
                for(var i=arguments.length,args=Array(i);i--;)args[i]=arguments[i];
                if(!func(args)) return superclass.prototype.add.apply(this, args);
            }
        }
    });

    return constructor;
}

或利用 ES6-类 (Classes#Mix-ins @ MDN)

var subclassFactory = (superclass, func) => class extends superclass {
    add(...args){  
        if(!func(args)) return super.add.apply(this, args);
    }
}