1

OOP suggests only exposing variables and methods that you want the user to be able to access. I have been using the public method declaration (i.e. prototype) for my object.

DrawShape = function() {

}

DrawShape.prototype.circle = function() {
    // draw logic here
}

DrawShape.prototype.square = function() {
    // draw logic here
}

This method seems to be the most efficient as the method isn't rewritten every time an instance in instantiated. However I have found that to create good DRY, modular code I have had to create methods that are only intended to be accessed by other methods (i.e. private methods).

DrawShape = function() {

}

DrawShape.prototype.circle = function() {
    var colour = this.setColour();
    // draw logic here
}

DrawShape.prototype.square = function() {
    var colour = this.setColour();
    // draw logic here
}

DrawShape.prototype.setColour = function() {
    return "blue";
}

Here I have created the method called setColour that is only intended to be run by the other methods. The problem is that the method is public and could be called by anyone or anything.

I could move the method into the object constructor... But this means that I am no longer saving memory (i.e. it will be rewritten every time an instance is instantiated) and it also means that I would have have to move all my other methods into the constructor.

What is the best practices in JavaScript when it comes to creating objects?

McShaman
  • 3,627
  • 8
  • 33
  • 46
  • possible duplicate of [JavaScript private methods](http://stackoverflow.com/questions/55611/javascript-private-methods) – Dagg Nabbit Dec 06 '13 at 02:40
  • If you have to have private methods then you can put them on the prototype within an IIFE `(function(){var private=function(){};o.prototype.priviliged=function(){private()};}())` I prefer to just use the naming convention and have privates start with an underscore. http://stackoverflow.com/a/16063711/1641941 covers some ways of privateness. (&*&&**%%$$!! just noticed that was already an answer, will leave the link, maybe it'll be helpful) – HMR Dec 06 '13 at 03:36
  • possible duplicate of [Prototypical inheritance - writing up](http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up) – Borodin Dec 06 '13 at 05:56

2 Answers2

5

The power of IIFEs (Immediately Invoked Function Expressions):

DrawShape = function() {

}

(function () {
    DrawShape.prototype.circle = function() {
        var colour = setColour();
        // draw logic here
        console.log(typeof setColour); // function
    }

    DrawShape.prototype.square = function() {
        var colour = setColour();
        // draw logic here
        console.log(typeof setColour); // function
    }

    function setColour() {
        return "blue";
    }
    console.log(typeof setColour); // function
})();
console.log(typeof setColour); // undefined

Note that if this is used in the setColour function, you'd have to call it with the current value of this, as you cannot reasonably bind this to a specific object (as far as I am aware, even ES6 does not make this easier):

setColour.call(this);

Anyway, those "u"s must hurt an American's eyes...

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
1

I would prefer this:

DrawShape = function() {
    var circle = function() {
        var colour = setColour();
        // draw logic here
    };

    var square = function() {
        var colour = setColour();
        // draw logic here
    };

    var setColour = setColour() {
        return "blue";
    };

    return {
        circle: circle,
        square: square
    };
};

I think it looks nice. And a readablity is good too.

EDIT:

According to comments we can rewrite it as follows:

DrawShape = function() {
    this.circle = function() {
        var colour = setColour();
        // draw logic here
    };

    this.square = function() {
        var colour = setColour();
        // draw logic here
    };

    var setColour = setColour() {
        return "blue";
    };

    return this;
};

I don't really like IIFCs.

Tony
  • 7,345
  • 3
  • 26
  • 34
  • Create an object and try `newobj instanceof DrawShape` http://jsfiddle.net/wS2AN/ – zerkms Dec 06 '13 at 02:42
  • 1
    The problem with this is that the actual prototype of the returned object is not `DrawShape.prototype` -- it is actually `Object.prototype`. – Qantas 94 Heavy Dec 06 '13 at 02:42
  • 2
    This would create its own copy of every function for every object created. Won't say it's a **RESOURCE CONSUMPTION** but it would still consume some CPU and memory – zerkms Dec 06 '13 at 02:48