tags:

views:

53

answers:

2

HI,

I have a JavaScript program that's written with object literal syntax:

var MyJsProgram = {

    someVar: value1,
    somevar2: value2,

    init : function() {
        //do some initialisation
    },

    libraryFunction : function() {

    },

    getStyle : function() {

    },

    extend : function() {

    }
}

There can be multiple instances of this script running at once. Should I move the common methods in to the prototype object of the myJsProgram? If so, is this syntax correct?

 var MyJsProgram = {

    someVar: value1,
    somevar2: value2,

    init : function() {
        //do some initialisation
    },

    //more methods/members here that are unique to each instance
}

myJsProgram.prototype = {
    //all shared methods here
}

?

+1  A: 

No, that syntax is not correct (no offense) ;)

You need to create an object for using its prototypes. That means that you need a constructor (which is a function in JavaScript). Applied to your problem:

var MyJsProgram = function (value1, value2) {
    // "this" refers to the current instance of this object
    this.someVar = value1;
    this.someVar2 = value2;
    // do some initialization
};

Create the new object like this:

var jsProgramInstance = new MyJsProgram(value1, value2);

Prototypes are instance members of those objects. They are defined like this:

MyJsProgram.prototype.someSharedMethodName = function () {
    // do shared method stuff here
    // (this.someVar and this.someVar2 are available here)
};

Use them like this (on your previously created instance):

jsProgramInstance.someSharedMethodName();

You should not do the following, since it overwrites the existing prototype properties that may exist (due to inheritance):

MyJsProgram.prototype = {
    someSharedMethodName: function () {
        // ...
    },
    // ...
};
elusive
no offsense taken :)
elduderino
+3  A: 

First, make a function, from which you can make instances

// Make it a function, so you can make a new instance
var stdProgram = function(){};

// All shared methods go here
stdProgram.prototype = {
  echo: function(message){
    alert(message);
  },
  extend: function(key, value){
    this[key] = value;
  }
};

Then you could make your specific 'programs', actually just instances of the base class

// And here you can make instances for specific programs
var myFirstProgram = new stdProgram(),
    mySecondProgram = new stdProgram();

myFirstProgram.extend('unique', function(){ 
  alert('I am unique');
});

mySecondProgram.aVar = 'test';

To make sure everything works, try this:

myFirstProgram.unique();     // Should alert I am unique
mySecondProgram.unique();    // Should throw an error, unique is undefined

alert(mySecondProgram.aVar); // Should alert test
alert(myFirstProgram.aVar);  // Should echo undefined

myFirstProgram.echo('hi');   // Should alert hi
mySecondProgram.echo('hi');  // Should alert hi
Harmen
This answer has more votes but elusives post below says not to use that syntax when creating the prototype because it will override any existing prototype properties. I know this is right but if I know that the only prototype properties are going to be in stdProgram.prototype = { } then it shouldn't matter...right?
elduderino
@elduderino: You _can_ overwrite the `prototype` property, but it is not recommended, since it breaks inheritance (which is what prototypes are all about).
elusive
@elusive...but why does that break inheritence? If I know that all the inherited properties are going to be in that prototype object then where does the inheritnce get broken?
elduderino
@elduderino: I do not see problems in this particular case, since you are not deriving from any object, but it is much easier to simply stay at a safe distance. This way you cannot get in trouble by accident.
elusive
@elusive. Yes understood. Just wanted to make sure there was a reason that I didn't know about why I couldn't use that method.
elduderino
@elduderino, I don't see the problem... Often the prototype of a class is set only once, and if any mutations are made, they are made with `.prototype.property = value`. So, as long as you use `prototype={};` at the first definition, there is no problem. If you need to alter it later on, you can just use `class.prototype.property = value`.
Harmen
@harmen Yes I was saying the same thing. What's the harm in doing that. Elusive was just saying that in general terms it's good practice to do it explicitly with MyJsProgram.prototype.MethodName to avoid overwriting things already in the prototype that are named the same
elduderino
Hi, I've just been reading crockford the good parts and on page 22 he says "All objects created from object literals are linked to object.prototype". Doesn't this mean that my original code is valid?
elduderino