• There are ways in Javascript to have private members - state and behavior | values and functions/methods - but I'm not seeing it done often. Some minimal discipline in following a few rules is good enough to mitigate the (worst) issues. No langue - no matter how strongly or inferred or even static ...typed and compiled compensates for ingnorance in the problem space... After acquiring a decent understanding what is going on and sorting the things out in the mind, a few formal rules consistently applied foster an equally decent implementation. These are a few rules I stick with... but as you know: Rules can only exist when Exceptions to the Rule(s) exist... ;-)...

    1. CamelCase and camelCase notation for all things (except for constants).
    2. Constants all UPPER_CASE and 'mimicking camelCasing' with UNDER_SCORES.
    3. Class names (which in Javascript are constructor functions are always starting with an UpperCase.
    4. Members - state or behavior - start with lowerCase, and - if you want to pay attention to public and private, prefix it them with single underscore (_).
    5. Above code uses private members - state (_inquiries) and behavior (_getXyz() ) to show what is all accessible from the outside and what should not be used for various reasons (hide implementation, allow change under the hood),...
    6. Since there is only a single name space - the global name space - available, keeping as little as possible globals is very helpful. Therefore, not even functions should freely float around: they belong to a function library, which is like a singleton, sometimes named xyzUtils or just utils. It is though a good thing to be somewhat specific what the utility library is about.

    var Person = function(first,last,birthDate) { // constructor expects String, String, Date
        this.first = first;
        this.last = last;
        this.birthDate = birthDate;
        this._inquiries = { ageInYears: 0, inquiries: 0 };
    }
    Person.prototype.getFullName = function() {
        return this.first + " " + this.last;
    }
    Person.prototype.getAgeInYears = function() {
        this._updateInquiries("ageInYears");
        return this._getAgeInYears();
    }
    Person.prototype.getNumberOfAgeInquiries­ = function() {
        this._updateInquiries("inquiries");
        return this._inquiries.ageInYears;
    }
    Person.prototype.getSumOfAllInquiries = function() {
        this._updateInquiries("inquiries");
        return this._getSumOfInquiries();
    }
    Person prototype.getYearlyAverageOfInquiries = function() {
        return this.getSumOfAllInquiries() / this._getAgeInYears();
    }
    Person.prototype._updateInquiries = function(fact) {
        this._inquiries[fact]++;
    }
    Person.prototype._getAgeInYears = function() {
        return new Date().getFullYear() - this.birthDate().getFullYear();
    }
    Person.prototype._getSumOfInquiries = function() {
        this._updateInquiries("inquiries");
        var sum = 0;
        for (var fact in this._inquiries) { sum += this._inquiries[fact]; }
        return sum;
    }
    
    var personUtils =
    { utilityFnctA: function(person,someOtherThing,andAThird­Thing) {
            // do what it has to do
        }
    , utilityFnctB: function(person,someXThing,someYThing) {
            // do what it has to do
        }
    };
    

    Since JavaScript by nature has closures, various frameworks have popped-up to overcome name space issues in order to mix and match components from various - non-synchronized - providers. One very useful library is node.js' require("module(Path)Name") and requirejs' require(["modulePathName1","modulePathNa­me2",...],function(module1,module2,...){­ ... };. The first one is more server-side oriented, and latter more client - Browser - side oriented. Both keep a cache to load a thing only once. The second goes though farther in functionality: first is usually synchronous, where the second one is usually asynchronous and handles the load of all modules like a promise and enters the anonymous function only after all modules have been loaded. In a 'small' world like an mc, the first one works just good enough.

    .

About

Avatar for allObjects @allObjects started