0

I'm working with namespaces, classes, inheritance and pattern chain of responsibility with JavaScript, but it doesn't work - I've tried following this tutorial, but when I try to implement a namespace and a super constructor, it doesn't works, so I assume I'm missing something.

I have the classes in different files, and I use the same namespace. I have a class, 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;
})();

And the next is the class that has inheritance, and it is in the other file, 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?

And the class 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());
        }
    }
 })();

And finally the file app.js, that is my Main:

 $(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);
     })
 });

I hope not to be very awkward, but I'm very confused.

So, my questions are:

  1. How can I properly use the namespace in different JavaScript files?
  2. How can I add a class without overwriting the namespace?
  3. How can I write the constructor of class with a namespace?
  4. How can I use the constructor of a class parent in the constructor of a class child?
  5. What is the right way to use inheritance classes with a namespace?
  6. How do I properly use the parents attributes in child classes?

This is a class Constraint(Parent Class):

/**
 *  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.**

The class StringConstraint (Child class):

/**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);

This is a Class 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;
})();

This is the 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
*/

You can see the code here: https://gist.github.com/cristianchaparroa/f4ace75aeb8cff04181a

1 Answer 1

1

You should do something like:

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;

})();

Inside the immediately invoked function expression (IIFE), you can call the function Constraint anything you like since the name is local to the function. The return value is a reference to that function object and is assigned to Namespace.Constraint.

Sign up to request clarification or add additional context in comments.

2 Comments

It resolve my questions, but how to I do to resolve the new mistake Uncaught TypeError: Object 0 has no method 'handle' in BuilderConstraint.js in the foreach, why my constraint not have my method handle?
The IIFE on the RHS of the assignment to Namespace.BuilderConstraint doesn't return anything, so Namespace.BuilderConstraint is undefined. If you've fixed that, post your new code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.