freedomflyer
freedomflyer

Reputation: 2541

What are some idiomatic ways to create custom Javascript objects

I am creating a custom object to be used in some internal applications where I work. I researched some ways to go about doing this - and this is what I came out with.

function ISGrader(text)
{
this.text = text;

this.printInfo = function(){
    alert("Object working " + text);    
}

this.putGrade = function(score)
{
           alert(score);
}
 }

I believe this shows constructor-type functionality, as well as some simple starter methods that I will build on.

Is the above good practice or is there another way that is more standard?

Upvotes: 2

Views: 219

Answers (5)

Anurag
Anurag

Reputation: 141859

I prefer a pattern similar to the one below. You can think of it as a 4-step approach:

(function(parent) {

// 1. Declare private variables and functions that will be
// accessible by everybody within the scope of this 
// function, but not outside of it.
var doSomethingAwesome = function() { .. }; // private function
var coolInteger = 42; // private variable

// 2. Create the constructor function
function ISGrader() {
    ..
}

// 3. Create shared public methods on the prototype object.
// These will be created only once, and shared between all objects
// which is more efficient that re-creating each method for each object.
ISGrader.prototype.printInfo = function() { .. };
ISGrader.prototype.putGrade = function(score) { .. };

// 4. Expose the constructor to the outside world.
parent.ISGrader = ISGrader;

})(window);

The reason why everything is enclosed inside a self-executing anonymous function is to ensure the private variables we create inside don't leak outside to the enclosing scope, and to basically keep things clean.

Another benefit of declaring the constructor like this is that you can change the parent object easily from say window to a further namespaced object by changing a single word.

Upvotes: 2

Diode
Diode

Reputation: 25135

It is always recommended to do it using `prototype'. This way you can also inherit it's properties and create new one.

var ISGrader = function(text) {
    this.text = text;

    var _privateVar = text;

    this.updatePrivateVar = function(newText) {
        _privateVar = newText;
        alert("private variable updated");
    }
}
ISGrader.prototype.text = "";
ISGrader.prototype.printInfo = function() {
    alert("Object working " + this.text);
}
ISGrader.prototype.putGrade = function(score) {
    alert(score);
}

var isGrader = new ISGrader("hello");
isGrader.printInfo();



// Inherit and create a new definition
var ISGrader2 = function() {}
ISGrader2.prototype = new ISGrader();

var isGrader2 = new ISGrader("hello2");
isGrader2.printInfo();
isGrader2.updatePrivateVar("hello3");

demo : http://jsfiddle.net/rkspP/3/

Upvotes: 1

Brian Glaz
Brian Glaz

Reputation: 15666

If you are planning on creating multiple ISGrader objects on a single page, it's more memory efficient to stick the functions in a prototype object assigned to ISGrader like this:

function ISGrader(text) {
    this.text = text;
}

ISGrader.prototype = {
    printInfo: function() {
        alert("Object working " + this.text);
    },
    putGrade: function(score) {
        alert(score);
    }
}

Upvotes: 0

sellmeadog
sellmeadog

Reputation: 7517

While not really an answer, I recommend Douglas Crockford's book JavaScript: The Good Parts as it does a good job of introducing you to the "good parts" of the language and discusses the pros and cons of the different ways to create objects in JavaScript.

You can also review this resource if you're just looking for an explanation of member visibility in JavaScript objects: http://javascript.crockford.com/private.html

Upvotes: 0

jbabey
jbabey

Reputation: 46647

I prefer this pattern (IIFE), but it is purely opinion:

var ISGrader = (function (text) {
    // anything declared here is "private"
    var printInfo = function() {
        alert("Object working " + text);    
    };

    var putGrade = function (score) {
        alert(score);
    };

    // put "publicly" accesible things in the returned object
    return {
        text: text,
        printInfo: printInfo,
        putGrade: putGrade
    };
})(text);

Upvotes: 2

Related Questions