子类工厂缺少原型 - Javascript

时间:2016-06-20 20:47:57

标签: javascript constructor subclassing

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

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

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

感谢任何帮助,谢谢。

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;
  }

2 个答案:

答案 0 :(得分:3)

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

请(根据经验),永远不要将arguments-object传递给任何函数。 您要避免将arguments-object传递给另一个函数。 它阻止了通过底层JS引擎的优化。改为使用spread-operator(ES6 Rest parameters @ MDN)或手动将Arguments复制到数组中。

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(Classes#Mix-ins @ MDN

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

答案 1 :(得分:0)

如果您第一次致电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. 始终传入一个在其原型链中某处定义add的超类对象

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

  4. 如果超类上不存在“add”方法,则将其默认为空函数

相关问题