If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Best way to create a reusable object/class

Hey,
I'm new to OOP in javascript.
What I have been doing so far to make a "class"/Reusable object is this:

PHP Code:

function Dog(){
this.name name;

this.bark = function(){
// some code
}
}

However, recently I have been reading a book on Javascript and it said that the problem with this way of doing it, is that the bark() function will be loaded into memory for each Dog object created this way, while the body of that function is the same for each object. There was an explanation on how it could be done better but I did not understand it fully.

Let's say I want:
- A Person class with a name property and a jump() method.
- An animal class with a isMammal property and move() method.
- A Dog class with a numberOfLegs property and a bark() method which is a subclass of Animal (thus inherits the isMammal property and move() method.
- Each of those classes in its own file.

What would these files look like when I do it the right way?

This book I've been reading is actually pretty good, but at some points it's explanation is not rich enough.

It explains that functions are objects and that objects in javascript are just key-value pairs. It says that each function has a prototype property which points to a blank Object(), but you can make it point to something else? or maybe I misunderstood it. I still don't understand how it really works. Maybe someone can give me a good link or explain me how the whole prototype thing works.

Hope you can help me out, it would really help me to start understanding Javascript better in its entirety. Because most things I can get working now, but I want to know why it works and whether I'm doing it in an efficient way.

... the problem with this way of doing it, is that the bark() function will be loaded into memory for each Dog object created ... What would these files look like when I do it the right way?

It would look like this:

PHP Code:

function Dog(name) {
this.name = name;
}

Dog.prototype.bark = function () {
// some code
};

The "prototype" property is automatically created with each function, and when you do new Dog(), the new object will inherit from Dog.prototype. So every instance of Dog will inherit and share the same copy of the function "bark".

Originally Posted by stefan2

... A Dog class ... which is a subclass of Animal ...

Inheritance in JavaScript can be an in-depth topic, because there are several techniques. But the most basic looks like this:

PHP Code:

function Animal() {
}

Animal.prototype.move = function () {
// some code
};

function Dog(name) {
this.name = name;
}

Dog.prototype = new Animal();

Dog.prototype.bark = function () {
// some code
};

We start with a basic "Animal" function, and we attach a "move" method to Animal's prototype, so every instance of Animal will inherit the move method. Then for "Dog", we replace the prototype object with an instance of Animal. That means every instance of Dog will also inherit the move method, because Dog instances inherit from Dog.prototype, and now Dog.prototype inherits from Animal.prototype.

// first create a Person constructor, which takes two arguments and sets them as properties of the created instance
function Person(name, age){
this.name = name;
this.age = age;
};
// add a function to the prototype, so that it shares the function on all instances of Person.
Person.prototype.sayName = function(){return 'Hi, I\'am '+this.name};
// next create a Worker constructor
function Worker(name, age, company){
Person.call(this, name, age); // call the Person contructor with the instance to be created as relevant object, so it can set the name and age properties.
this.company = company; // add another property
}
Worker.prototype = new Person; // set the Worker prototype to the Person prototype
Worker.prototype.constructor = Worker; // set the constructor back to Worker
Worker.prototype.sayCompany = function(){return 'I work at '+this.company} // extend the Worker prototype
Worker.prototype.sayName = function(){ //overwrite the sayName function
return Person.prototype.sayName.call(this) +'. '+ this.sayCompany(); // call the Person.sayName, and add some
};

One thing to consider is that when inheriting from another constructor using Sub.prototype = new Base, can cause problems the Base constructor requires an argument.
for example:

Code:

function Sub(){}.prototype = new function Base(date){date.getDay()}; // Error: undefined does not have the method getDay();

This way I can create 1000 Dog objects which all share the same function (in memory).

Also thanks for the book suggestions. The book I was talking about actually was Javascript Patterns, which is a great book, but I'm missing some basics, so maybe I will buy the Object-Oriented Javascript book.

Let's see if I understand it correctly now:
If you do: Dog.prototype = ....
- Then you're setting the prototype property of the Dog object.
- The prototype property is pointing to an object, by default Object(), but you can set it to any other object.
- You can add functions and properties to that object.
- Each time a Dog object is created it gets all the functions and properties of the object that was set as prototype.
Is this right?

Let's see if I understand it correctly now:
If you do: Dog.prototype = ....
- Then you're setting the prototype property of the Dog object.
- The prototype property is pointing to an object, by default Object(), but you can set it to any other object.
- You can add functions and properties to that object.
- Each time a Dog object is created it gets all the functions and properties of the object that was set as prototype.
Is this right?

As much as I loathe the using the prototype property (it's ugly, roundabout, and unorganized looking), it not only comes with significant memory savings, but there's also a significant efficiency advantage when calling prototyped methods versus non-prototyped methods. In my benchmarks, it ranges between 13.5% and 21.7%.

But, bear in mind that, while this is a really significant improvement percentage-wise, it's not a noticeable improvement unless you're writing incredibly "busy" code. If you're writing a game, for example, and tracking thousands or hundreds of thousands of objects, trying to call various methods on each of those objects hundreds or thousands of times per tick with 20 or 30 ticks/second, you may benefit from the 13% to 22% boost. And you may see even bigger gains if your application has started paging. Though, chances are your DOM/Canvas calls are the real overhead if you're pushing the limits.

However, if you're NOT making in excess of 10 million method calls/second and are instead doing some simple AJAX stuff, polling for new message every 5 seconds or so, using the prototype isn't at all necessary. No one will notice a 22% efficiency gain on an overhead of 0.000022ms. And the same goes for the negligible amounts of extra memory you'll be consuming.

Applications that are pushing the limits may very well see benefits from using the prototype version:

However, most applications can stand to use the version that is, in my opinion, prettier and more organized:

Code:

var ClassName = function() {
this.method = function() {
}
}

One of the first things I was taught in my CS studies: The better solution is the one that best meets the applications specific needs. Sometimes it's efficiency, sometimes it's a small footprint, sometimes it's the solutions is fastest or easiest to implement, and sometimes it's just the code that's easiest to read and maintain.

One of the first things I was taught in my CS studies: The better solution is the one that best meets the applications specific needs. Sometimes it's efficiency, sometimes it's a small footprint, sometimes it's the solutions is fastest or easiest to implement, and sometimes it's just the code that's easiest to read and maintain.

Fortunately, these days we don't need to choose between readability and performance. There are libraries that will let you write code in the style you prefer, while still using prototypes under the hood.

Yeah you got a point there.
When I was doing Java programming at college, they taught us to write neat code rather than the most efficient code.

I'm actually (trying) to make a RTS game, with possibly alot of objects on the field. So when I found out that the way I had been creating "reusable-objects" was not very efficient, I had to know how I could do it more efficiently.

I actually have no idea whether creating a heavy game in Javascript/html5/css is even doable, there's so many things involved with RTS games. Drawing all units on the screen every so many times per second, keeping track of a grid to do path finding for all objects, collision detection, rotating images in the canvas (if you want 360 degree turning rather than a fixed set of directions), etc. Sometimes I start to think it's a bit too much to handle, but I don't really know.

I know there are probably much better languages and libraries available for creating games, but I see it as an interesting project to do it with (mainly) Javascript. Also I actually like to write everything myself, its a better way to learn for sure, because you run into so many small problems while doing so, from which you really learn alot.

I actually have no idea whether creating a heavy game in Javascript/html5/css is even doable, there's so many things involved with RTS games. Drawing all units on the screen every so many times per second, keeping track of a grid to do path finding for all objects, collision detection, rotating images in the canvas (if you want 360 degree turning rather than a fixed set of directions), etc. Sometimes I start to think it's a bit too much to handle, but I don't really know.

you'de have to do all those things in any language to make the game, javascript is just the open way of doing it.

svg and webGL expose quite a bit of rendering capability.
heck, css3 does quite a bit of neat stuff alone.

lots of games were made in AS2, and AS2 is essentially strong typed javascript with a class library...

for performance, web workers are much faster at crunching numbers and searching objects than normal browser javascript, but the message passing and file-loading can be cumbersome to work with. but, If you can base your main engine in worker threads, your game animations won't be as likely to slow down or drop frames since the animation and constant calculations are on different threads... boot up your worker, and fill it using messages, synching with the gui to transmit game events and state changes.

having higher performance on the slow parts enables you to use easier coding patterns (like functional or oop) to create RADical solutions.

I re-ran my benchmarks (I had to!) in a slightly more controlled environment, under more fair, compartmentalized conditions, ensuring that new page-sessions were open for each set of tests. And I found that one of my previous results was not necessarily accurate. (It's possible that the statement was "accurate" under certain conditions. But, I couldn't say what those conditions would be.)

I had previously stated, there's also a significant efficiency advantage when calling prototyped methods versus non-prototyped methods. In my benchmarks, it ranges between 13.5% and 21.7%. And at the the of that statement, I had run several permutations of the tests. But, I have since been unable to show any consistent difference. I would be interested to see others' benchmarks under various conditions. However, I've run iterative tests under fresh window loads with a variety of object instantiation syntaxes, and this particular point has proven to be mistaken.

The following two calls are, according to my tests, of equivalent efficiency:

Code:

a.add(1,1);
b.add(1,1);

Possible explanation: This latest suite of tests dwarfs any difference in the method-call with other logic: a method wrapper for the benchmarking loop, modulo arithmetic to pick an object instance, and a incrementor (actually two, if you count the one running the benchmark loop), and the method logic itself (adding p1 + p2 and returning). However, if the difference is so easily dwarfed into total undectability, it's probably not worth noting.

The object instantiation cost is much more significant, yielding a 51% savings using the prototype (a 106% performance hit by not using prototype). An object helper class, a bit simpler than the one Jeff Mott posted, shows no significant efficiency difference. And Jeff's example introduces about 15.8% efficiency during object instantiation over using the prototype directly (not sure where this efficiency hit could be occurring -- haven't really studied the code). I would estimate that the efficiency gap widens as the class methods become larger. Since I don't know where the efficiency hole in Jeff's code is, I can't say what would widen or shrink that gap.

I haven't looked at any of these in terms of memory consumption. And all benchmarks were performed in Chrome on OS X. Based previous benchmarks for different constructs (such as array creation), I am assuming that the results are similar, with slightly varying magnitude/significance.

So, stefan2 ... If you're attempting to perform hundreds of thousands of object instantiations per second, definitely use prototype. If you're instantiating a bunch of objects (even in the millions) all at once and then just calling their methods at a high rate, you're probably OK either way. But, you may run into memory problems in you have a lot of bulky objects, objects with many and/or large methods.

Find a system like Jeff's. De-obfuscate it, if you need to. (It seems obfuscated to me.) And find that tiny 15% efficiency hole if it's causing you any trouble (it probably won't).

keep in mind that there is a higher property-name resolution cost on prototypes than there is on own properties. If a prototype get chained 2 or 3 (or 20) levels deeps, there's a lot of potentials to strike off the list before the correct prototype appears.

your two methods are identical pure functions, so there's no reason to tote them around with the objects.
the main advantage of binding methods in-constructor is making use of the privileged pattern, aka having access to closure inside the constructor.

if you don't need closure, but do need direct object association, use prototypes.
if you don't need either (the example given doesn't), use a 3rd-party method container:

I won't be needing that many objects, but I guess I can better do things the efficient way now, than rewriting my entire code of the game too make it run properly, in the end.

Also I will be enclosing each constructor + prototype code into a separate file. At least for all the game-objects and the helper-objects like Vector, Table, Stack, etc. This way the prototype code isn't as chaotic, everything just has it's own file.