Constructor function - in simple namespace - Javascript

It is required to define a constructor of functions inside a namespace. The way I've defined the constructor so far has been a simple non-NS constructor function combined with prototypal inheritance.

The code looked like:

 function mySuperObject() {
    var self = this;
    self.p1 = "";
    self.p2 = "jkejie";
    // and others
    }
 mySuperObject.prototype.func1 = function(){...}
 // and others

      

Namespace representation:

After reading many articles, I decided to start with a very simple way to define a namespace, perhaps the simplest. Basically it is just a definition of a variable that points to a literal object, and the content is an object ("mySuperObject" in the code snippet above). The constructor function is as follows: mySuperObjectInNS.

Object code:

var MYNAMESPACE = {

    //some variable outside the object
    file : "ConstructorInNamespace_obj.js: ",

    //Defining contructor function inside a namespace
    mySuperObjectInNS : function(propOne, propTwo){

        var self = this;
        self.objectName = "mySuperObject";
        self.propertyOne = propOne;
        self.propertyTwo = propTwo;

        self.doSomething = function(){
            console.log(file + " doSomething called - function of object");
        };

        ///many more functions and attributes
    }
}

MYNAMESPACE.mySuperObjectInNS.prototype.specialFunction = function(){
    console.log(file + " specialFunction called - prototypical inheritance defined in file of object, outside of namespace");
};

///many more functions and attributes

      

In another file, you can see the object like this:

...
var objOne = new MYNAMESPACE.mySuperObjectInNS("param11", "40");
//following line works just fine
objOne.doSomething();
 ....

      

Questions:

  • It seems to me that this is all related to the definition of Object-Literal and I will be facing the last problems that I am trying to define the "private" properties of this object. It's right?
  • Is mySuperObjectInNS still a constructor function? (To me it seems like it is something else, even if I can infect objects from it.
  • Is this a very bad way of generating names, or does it look ok?
+3


source to share


1 answer


It seems to me that this all has to do with the definition of Object-Literal, and I will run into the last problems I am trying to define for the "private" properties of this object. Is it correct?

"Private properties" have nothing to do with using the object for the namespace. In fact, originally when answering this question, I read it as "private functions" because this one was relevant.

There are many ways to make private and semi-private properties in JavaScript, but they have to do with how you create the constructor function and the methods it provides to the object, not how you expose the constructor function. Namespace objects describe how you expose the constructor.

One common pattern for creating "private" properties is to define methods that need to access them inside the constructor, and make the local variables of the properties inside the constructor (so they are not properties at all), for example

function SuperObject() {
    var privateInformation;

    this.method = function() {
        // This can access `privateInformation`, which is completely
        // hidden from outside the constructor
    };
}

      

It doesn't matter if you do it in the "namespacing" template or on your own.

Private functions , on the other hand, affect the template. I'll show both below.

A fairly common option that provides private functions is to use a function to create an object, which also gives you the ability to create private functions:

var TheNamespace = function() {
    function privateFunction() {
    }

    function SuperObject() {
        var privateInformation;

        this.method = function() {
            // This can access `privateInformation`, which is completely
            // hidden from outside the constructor
        };
    }

    SuperObject.prototype.otherMethod = function() {
        // Can't access `privateInformation`, but has the advantage
        // that the function is shared between instances
    };

    return {
        SuperObject: SuperObject
    };
}();

// usage
var s = new TheNamespace.SuperObject();

      

Is mySuperObjectInNS still a constructor function? (I feel like it's something else, even if I can impose objects on it.

Yes. A constructor function is any function that expects you to use new

it.

Is namespacing a very bad very bad way or kind of ok?

Using objects as pseudo-spatial spaces is common practice. You might also want to consider the various Asynchronous Unit (AMD) technologies , which largely make "namespace" objects largely unnecessary.


Your comment:

Have you defined a self-invoking .... function that returns an object?

It is not a self-dependent function, it is a built-in function, but yes, it is a function that returns an object.

(if so, I think the parentheses are missing)

No, we don't need any pairs that aren't there, because the only reason for the outer parens of other places you've seen this is to tell the parser that the word function

begins an expression, not a declaration; we don't need this because we are already on the right side of the assignment, so there is no ambiguity when it comes across function

.



Because you suggested this way, is this the best way to define ns?

Better is a subjective term. This gives you an area where you can define the private functions you asked for.

While I've often also seen the option: var = {} | someNSName;

What is it?

If you have multiple files that will add things to the "namespace" (as is usually the case), you often see this in each of them:

var TheNamespace = TheNamespace || {};

      

What it means is, declares a variable if it hasn't already been declared previously, and assigns it an empty object if it doesn't already have it. In the download file, this happens first :

  • The handler is var

    processed and creates a new variable TheNamespace

    with a value undefined

    .

  • The assignment is TheNameSpace = TheNameSpace || {}

    processed: since false undefined

    , the curiously powerful ||

    operator
    results in a new {}

    one that is assignedTheNamespace.

When the next file is loaded, this happens:

  • var

    is a non-op because the variable already exists.

  • The assignment is TheNameSpace = TheNameSpace || {}

    processed: since it TheNamespace

    has no object reference null

    , it is truthful, and the curiously powerful ||

    operator results in the object TheNamespace

    reference refers to.

That is, it has no effect.

This is used so that you can upload files in any order, or upload only one file at a time.

Here's an example:

thingy.js

:

var TheNamespace = TheNamespace || {};
TheNamespace.Nifty = function() {
    function privateFunction() {
    }

    function Nifty() {
        var privateInformation;

        this.method = function() {
            // Can access `privateInformation` here
        };
    }

    Nifty.prototype.otherMethod = function() {
        // ...
    };

    return Nifty;
}();

      

thingy.js

:

var TheNamespace = TheNamespace || {};
TheNamespace.Thingy = function() {
    function privateFunction() {
    }

    function Thingy() {
        var privateInformation;

        this.method = function() {
            // Can access `privateInformation` here
        };
    }

    Thingy.prototype.otherMethod = function() {
        // ...
    };

    return Thingy;
}();

      

This basic template has lots of options, especially if a single file can add multiple elements to TheNamespace

. Here's the one that supports it rather succinctly:

var TheNamespace = function(exports) {
    function privateFunction() {
    }

    function Nifty() {
        var privateInformation;

        this.method = function() {
            // Can access `privateInformation` here
        };
    }

    Nifty.prototype.otherMethod = function() {
        // ...
    };

    exports.Nifty = Nifty;

    function Thingy() {
        var privateInformation;

        this.method = function() {
            // Can access `privateInformation` here
        };
    }

    Thingy.prototype.otherMethod = function() {
        // ...
    };

    exports.Thingy = Thingy;
}(TheNamespace || {});

      

+4


source







All Articles