命名空间和继承:具有JavaScript责任链的超级构造函数

时间:2013-09-26 00:37:15

标签: javascript class inheritance namespaces chain-of-responsibility

我正在使用JavaScript来处理名称空间,类,继承和模式责任链,但它不起作用 - 我尝试过this tutorial,但是当我尝试实现命名空间和超级构造函数,它不起作用,所以我假设我错过了什么。

我有不同文件中的类,我使用相同的命名空间。我有一个班级Constraint.js

var Namespace = Namespace || {};

//parent class
Namespace.Constraint = (function() {

    //How can I do a constructor with the namespace?
    /**
        function Namespace.Constraint(value, succesor, type) {
            this.value = value;
            this.succesor = succesor;
            this.type = type;
            this.noTopic = "UNDEFINED";
        }
    */

    Namespace.Constraint.prototype.handle = function() {
        if (this.has()) {
            return this.succesor.handle();
        }
    }
    Namespace.Constraint.prototype.has = function() {
        return this.type != this.noTopic;
    }
    return Constraint;
})();

接下来是具有继承的类,它位于另一个文件StringConstraint.js中:

 var Namespace = Namespace ||{};

 Namespace.StringConstraint = (function(_super){

     /**Constructor child*/
     /*
     Namespace.StringConstraint = function(value, succesor) {
         _super.call(value, succesor, "string");
         How to call the constructor of the parent?
     }
     */

     Namespace.StringConstraint.prototype.handle = function() {

         if (this.has()) {
            return "type=text";
         }
         else{

            /* Is this the correct way to call a method of the parent? */
            _super.prototype.handle.call(this);
         }
     }

     Namespace.StringConstraint.prototype.has=function(){
        /* this.type is a value of parent class. Is this the correct way
           to call it? Maybe I should use _super.type?

        */
        return this.type === "string";
     }
     return Namespace.StringConstraint;

 })(Namespace.Constraint); //Reference to parent, but is it fine with the namespace?

班级BuilderConstraint.js

 var Namespace = Namespace ||{};

 Namespace.BuilderConstraint = (function() {
     this.constraints = new Array();

        Namespace.BuilderConstraint.prototype.add = function( constraint ) {
            this.constraints.push(constraint);
        }
        Namespace.BuilderConstraint.prototype.applyConstraint  = function(callback) {
        for (constraint in this.constraints) {

            //How to ensure that class is Constraint?
            //Because I could get object [index], has not a method handle.
            callback(constraint.handle());
        }
    }
 })();

最后是文件app.js,即我的主要文件:

 $(function() {
     var value = "string";
     var builderConstraint = new Namespace.BuilderConstaint();
     var stringConstraint = new Namespace.StringConstraint(value,null);
     builderConstraint.add(stringConstraint);

     builderConstraint.applyConstraint(function(out) {
         console.log(out);
     })
 });

我希望不要太尴尬,但我很困惑。

所以,我的问题是:

  1. 如何在不同的JavaScript文件中正确使用命名空间?
  2. 如何在不覆盖命名空间的情况下添加类?
  3. 如何使用命名空间编写类的构造函数?
  4. 如何在中使用类父类的构造函数 班级孩子的构造者?
  5. 将继承类与命名空间一起使用的正确方法是什么?
  6. 如何在子类中正确使用父属性?
  7. 这是一个类约束(父类):

    /**
     *  Clase padre
     */
    
    var XMLFormBuilder  = XMLFormBuilder  || {};
    
    XMLFormBuilder.Constraint= (function()
    {
        function Constraint( value, succesor, type ) {
        this.value = value || "UNDEFINED";
        this.succesor = succesor || null;
        this.type = type || "UNDEFINED";
        this.noTopic = "UNDEFINED";
    };
    
    Constraint.prototype.handle = function()
    {
        if (typeof null != this.succesor ) {
        {
           return this.succesor.handle();
        }
    };
    
    Constraint.prototype.has = function()
    {
        return this.type != this.noTopic;
    };
    
    return Constraint;
    
    })(); // <-- **Here, there is a trouble.**
    

    班级StringConstraint(儿童班):

    /**Child class*/
    var XMLFormBuilder = XMLFormBuilder || {};
    
    XMLFormBuilder.StringConstraint=(function(_super)
    {
        function StringConstraint(value, succesor)
        {
            this.value = value || "UNDEFINED";
            this.succesor = succesor || null;
            _super.call( this.value, this.succesor, "cadena" );
    
           /**
            * How to I do to use the constructor of class parent in the constructor of class child?
            * Aquí hay un error, porque no se como llamar correctamente al contructor
            * de la clase padre o como lo sugiere el error que _super no esta definido.
            * Cannot call method 'call' of undefined;
           */
    
        };
        /* Aquí se genera un error si activo la sobreescritura del prototipo:
            Uncaught SyntaxError: Unexpected token ) /entidad/js/Constraint.js:28
            Uncaught TypeError: undefined is not a function StringConstraint.js:16
            Uncaught TypeError: undefined is not a function
    
            There is a trouble, because I can't overwrite the prototype
        */
        //StringConstraint.prototype = new _super;
    
        StringConstraint.prototype.handle=function()
        {
            if(this.has())
                return "type='text'";
            else
               return _super.handle();
        };
    
        StringConstraint.prototype.has = function()
        {
            return this.type === "cadena";
        }
    
        return StringConstraint;
    
        })(XMLFormBuilder.Constraint);
    

    这是一个班级BuilderConstraint

    var XMLFormBuilder = XMLFormBuilder || {};
    
    XMLFormBuilder.BuilderConstraint = (function()
    {
        function BuilderConstraint() {
            this.constraints = new Array();
        }
        BuilderConstraint.prototype.add = function(constraint){
            this.constraints.push(constraint);
        }
    
        BuilderConstraint.prototype.applyContraints = function()
        {
            var out = "";
            /*
                this.constraints.forEach(function(object){
                    out += object.handle();
                });
            */
    
            for (var index in this.constraints) {
                var constraint = this.constraints[index];
                /* Aquí se me presenta un error, ya que no me
                *  reconoce el método handle de los objetos tipo Constraint
                *  que agrege al array
                */
                out+= constraint.handle();
            }
            return out;
        }
        return BuilderConstraint;
    })();
    

    这是app.js

    $(function()
    {
        var value = "cadena";
        var stringConstraint = new XMLFormBuilder.StringConstraint(value);
        var builderConstraint = new XMLFormBuilder.BuilderConstraint();
        builderConstraint.add(stringConstraint);
        console.log(builderConstraint.applyContraints());
    });
    
    /**
    * This is the summary the problems:
    *   Uncaught SyntaxError: Unexpected token ) Constraint.js:28
    *   Uncaught TypeError: Cannot call method 'call' of undefined
    */
    

    您可以在此处查看代码:https://gist.github.com/cristianchaparroa/f4ace75aeb8cff04181a

1 个答案:

答案 0 :(得分:1)

您应该执行以下操作:

Namespace.Constraint = (function(){

   // Create a function in the current execution context
   function Constraint( value, succesor, type ){
      this.value = value;
      this.succesor = succesor;
      this.type = type;
      this.noTopic = "UNDEFINED";

  }

  // Assign to the above function's prototype
  Constraint.prototype.handle =function(){
     if( this.has() ){
         return this.succesor.handle();
      }
  }

  Constraint.prototype.has = function(){
     return this.type != this.noTopic;
  }

  // Return the function so it is assigned to Namespace.Constraint
  return Constraint;

})();

在立即调用的函数表达式(IIFE)中,您可以调用函数 Constraint 任何您喜欢的函数,因为该函数的名称是本地的。返回值是对该函数对象的引用,并分配给 Namespace.Constraint