How to do Prototype-based OO in JavaScript?

J

jangchoe

I've heard that JavaScript is a prototype-based language instead of a
class based one. I'm interested in learning the prototype-based
paradigm of OO programming, but I am unsure of the best way to use
JavaScript as a prototype-based language. I'm stuck between two ways
and both methods might be right (or wrong).

Method 1:

/* create an Animal "object" */
function Animal() {} ;

/* "copy" the animal object to a new object mouse */
var mouse = new Animal();

/* create a method to the animal */
Animal.prototype.speak = function() { alert('squeak!'); };
mouse.speak(); /* alerts squeak! */

Method 1 doesn't really feel like it's true prototype-based because I
need to instantiate it using 'new' instead of cloning an object like
Io or Self. So I created a second method that just uses JavaScript
objects, which to me, feels a bit more prototype-based.

Method 2:
/* create an Animal object */
var Animal = {}; // same as var Animal = new Object();

/* "copy" the animal object to a new object mouse */
var mouse = Animal;

/* create a method to the animal */
Animal.speak = function() { alert('squeak!'); };
mouse.speak(); /* alerts squeak! */

There's also a method three which basically combines both methods.
function Animal() {};
var mouse = new Animal();
mouse.speak = function() { alert('squeak!'); };
mouse.speak();

But if I use method 3, I wouldn't know why I created an empty Animal
function if I was going to dynamically add new methods to the objects
it instantiated. So based on the 3 methods above (or an entirely new
method) which simulates prototype-based programming in JavaScript?
Thanks.
 
N

noagbodjivictor

Hi,
Isn't prototype-based programming also called instance-based
programming?
 
G

Geoffrey Summerhayes

I've heard that JavaScript is a prototype-based language instead of a
class based one. I'm interested in learning the prototype-based
paradigm of OO programming, but I am unsure of the best way to use
JavaScript as a prototype-based language. I'm stuck between two ways
and both methods might be right (or wrong).

Method 1:

/* create an Animal "object" */
function Animal() {} ;

/* "copy" the animal object to a new object mouse */
var mouse = new Animal();

/* create a method to the animal */
Animal.prototype.speak = function() { alert('squeak!'); };
mouse.speak(); /* alerts squeak! */

Method 1 doesn't really feel like it's true prototype-based because I
need to instantiate it using 'new' instead of cloning an object like
Io or Self. So I created a second method that just uses JavaScript
objects, which to me, feels a bit more prototype-based.

The above makes all Animals squeak.
Method 2:
/* create an Animal object */
var Animal = {}; // same as var Animal = new Object();

/* "copy" the animal object to a new object mouse */
var mouse = Animal;

/* create a method to the animal */
Animal.speak = function() { alert('squeak!'); };
mouse.speak(); /* alerts squeak! */

So does method 2, but nastier:

var Animal={};
var Mouse=Animal;
var Cat=Animal;
Cat.Eats='mouses(sic)';
alert(Mouse.Eats); // ouch!

There's also a method three which basically combines both methods.
function Animal() {};
var mouse = new Animal();
mouse.speak = function() { alert('squeak!'); };
mouse.speak();

FWIW...

function Animal(){};
/* Don't know what type of animal I am so... */
Animal.prototype.speak=function(){alert('*grim silence*')};

function Mouse(){};
Mouse.prototype=new Animal();
/* I'm a generic mouse so... */
Mouse.prototype.speak=function(){alert('squeak!')};

function Cat(){};
Cat.prototype=new Animal();
/* Not a cat person, so they can keep quiet */

var foo=new Animal();
var tom=new Cat();
var jerry=new Mouse();
var mortimer=new Mouse();
mortimer.speak=function()
{
alert("I can talk! Where's the cheese?")
};

foo.speak();
tom.speak();
jerry.speak();
mortimer.speak();
 
J

jangchoe

So does method 2, but nastier:

var Animal={};
var Mouse=Animal;
var Cat=Animal;
Cat.Eats='mouses(sic)';
alert(Mouse.Eats); // ouch!

Yikes, ouch is right.

I found another method by more researching. It's using Crockford's
function for prototypical inheritance.

Object.prototype.clone = function() {
function TempClass() {};
TempClass.prototype = this;
return new TempClass();
}

Animal = {};
var Mouse = Animal.clone();
var Cat = Animal.clone();
Cat.eats = 'mouses';
alert(Mouse.eats); // Not ouch.

/* and using your example */
Animal.speak = function() { alert('*grim silence*'); };
var Mouse = Animal.clone();
Mouse.speak = function() { alert('squeak!'); };
var Cat = Animal.clone();
Cat.speak = function() { alert('hiss!'); };

var foo = Animal.clone();
var tom = Cat.clone();
var jerry = Mouse.clone();
var mortimer = Mouse.clone();
mortimer.speak = function() { alert("I can talk! Where's the
cheese?"); };

foo.speak();
tom.speak();
jerry.speak();
mortimer.speak();

I kind of like this method better. I guess I don't like that 'new'
keyword in JavaScript which makes me think that I'm not dealing with
objects like a true prototype-based language. It feels like I'm still
dealing with Classes.
 
J

John G Harris

I've heard that JavaScript is a prototype-based language instead of a
class based one. I'm interested in learning the prototype-based
paradigm of OO programming, but I am unsure of the best way to use
JavaScript as a prototype-based language. I'm stuck between two ways
and both methods might be right (or wrong).

Method 1:

/* create an Animal "object" */
function Animal() {} ;

/* "copy" the animal object to a new object mouse */
var mouse = new Animal();

/* create a method to the animal */
Animal.prototype.speak = function() { alert('squeak!'); };
mouse.speak(); /* alerts squeak! */

Method 1 doesn't really feel like it's true prototype-based because I
need to instantiate it using 'new' instead of cloning an object like
Io or Self. So I created a second method that just uses JavaScript
objects, which to me, feels a bit more prototype-based.
<snip>

Javascript is not like conventional prototype-based languages. You don't
create an object by cloning from a 'prototype' object.

Forget Io and Self; javascript is different!

John
 
R

RobG

I've heard that JavaScript is a prototype-based language instead of a
class based one. I'm interested in learning the prototype-based
paradigm of OO programming, but I am unsure of the best way to use
JavaScript as a prototype-based language. I'm stuck between two ways
and both methods might be right (or wrong). [...]
Method 2:
/* create an Animal object */
var Animal = {}; // same as var Animal = new Object();

/* "copy" the animal object to a new object mouse */
var mouse = Animal;

That doesn't "copy" the Animal object, it creates a second reference
to the same object. When the right hands side of an assignment is an
object, it's pseudo-code is "assign a reference to...".
 
P

Peter Michaux

You heard right. Objects can inherit from objects.

var animal = {
speak: function () {
alert('Hello, world!');
}
};
var mouse = animal.beget();
mouse.speak();

Seehttp://javascript.crockford.com/prototypal.html

With this beget system if you have many animals to produce and have to
name them all you wouldn't want to write like the following
(especially if there were more properties to set)

var mouse = animal.begat();
mouse.name = "Harold";
var cat = animal.begat();
cat.name = "Martha";
....

It would be much handier to have a function that automates this

function makeAnimal(name) {
var a = animal.begat();
a.name = name;
return a;
}
var mouse = makeAnimal("Harold");
var cat = makeAnimal("Martha");

and now here I am back at the same issue of having a constructor but
one that is is less efficient (download time, construction time) then
JavaScript's native constructor:

function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function(){...};

var mouse = new Animal("Harold");
var cat = new Animal("Martha");

What is the big gain from begat()?

Thanks,
Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top