views:

64

answers:

6

I've been looking into Javascript prototyping recently, can understand the theory, and believe it can be very useful to my understanding of the language, but can't quite get the following to work...

var player = function(){//Declarations here};
var super_player.prototype = new player();

Every compiler/checker flags a 'missing semicolon' error on line 2. I'm stumped, but believe that I am overlooking something really simple.

Can someone point me in the right direction?

A: 

Did you want to say

super_player.prototype.player = function(){ /*Declarations here*/ };

?

Vlad
+2  A: 

The engine doesn't know that super_player is a function until you declare it as one and hence it doesn't have a prototype.

var player = function () {},
    super_player = function () {}

// now we can happily set the prototype :)
super_player.prototype = new player();

// don't forget to point the constructor back to super_player
// not doing so will cause great confusion
super_player.prototype.constructor = super_player
Russ Cam
+2  A: 

Your comment on line 1 is blocking the ending brace. So you have a dangling open brace which won't work. You can change it to the following:

var player = function() {
   // Declarations here
};

If I were you I think you want to consider using camel case class names doing the following:

function SuperPlayer() {
}

function Player() {
}
Player.prototype = new SuperPlayer();
Player.prototype.constructor = SuperPlayer;

That will make SuperPlayer the base class, and Player the derived class as Player inherits from SuperPlayer through it's prototype. Not the other way around as you have in your example above.

chubbard
I will have to study your answer in more detail. What's more, thank you for picking up on the syntax error generated by my inline comment. It's not in my working example, but I should know better when I post here! ^_^
Charlie
+3  A: 

You want to do something like

function Player() {
    // player things here

}

Player.prototype = new SuperPlayer(); // get all the things on SuperPlayer prototype
Player.prototype.constructor = Player;

assuming SuperPlayer is the super class of Player, as it were.

edit -- If SuperPlayer is a better player, i.e. a subclass of Player, just reverse the above pattern

function SuperPlayer() {
        // super player things here

    }

    SuperPlayer.prototype = new Player(); // get all the things on Player prototype
    SuperPlayer.prototype.constructor = SuperPlayer;  // the above line changed the     constructor; change it back

I couldn't tell from what you wrote if SuperPlayer is a subclass or not. Also, other answers have pointed out that the code you posted as is syntactically broken, due to the comment...

hvgotcodes
The other way round actually. :} I was thinking along the lines of 'super', alluding to an augmentation, rather than a basis. Sorry!
Charlie
A: 

Was looking over chubbards' answer once more... The prototype keyword can be best described as unwieldy... It's strange, because it is most certainly OOP, but the implementation is crazy!

To take a common example...

mammal() = object;
cat() = prototype; // Implements mammal();
tiger() = object; // Implements cat(), but does NOT require the 'prototype' keyword... like some kind of 'cystalline' form? I can then create a whole range of individual 'tigers', but will not be able to add any new properties to any of them...

How about this instead?:

machine() = object;
car() = prototype; // Implements machine. It's a machine afterall...
super_car = prototype; // It's a very fast car...
ferrari = prototype; // They only make supercars...
ferrari_355 = object; // One of the best cars they've ever made. No need to change it, right? :}

Am right? :|

Charlie
What you've written is just a structure, but not Javascript. If you find the prototype inheritance concept strange (as do a lot of people), then you can use other Javascript libraries, like ExtJS or prototype, that offer methods for declaring object hierarchies in a more natural way. Prototype is a property of Function. It can't be used alone. So you have to have: cat.prototype = new mammal(), or tiger.prototype = new cat(). With something like Ext.JS you can do things like cat.extends( mammal ). Under the covers it does the roughly the same thing.
chubbard
It's hard to respond since we only get 600 characters. I'll try to be brief. Javascript uses functions to define not only regular functions, but also concepts like Classes. Functions that start with capital letters signify functions that are constructors. When we write 'new SomeObject()'. The new keyword allocates an empty object, sets the this keyword to that new object, then invokes the function SomeObject. SomeObject can then provision that object with data members using this.someMember syntax. Thus making SomeObject like a constructor...
chubbard
Now prototype is a property that every function has. This property forms a chain for which property resolution takes place. When a property is referred on an object it first looks inside that object for a property, if that property doesn't exist it then looks into the prototype for a property with the same name, and continues up the chain following prototypes until it finds it. It's mimics how same OO languages work for resolving members in an inheritance hierarchy. The reason we create a new SomeObject() is so any instance variables created in that constructor are initialized.
chubbard
A: 

Much respect to you Chubbard. :)

Your example helped a lot.

My original 'example' was rather flippant. :P

I'm still running into a handful of problems though... To elaborate on my 'cat' sample (keeping things as brief as possible):

function mammal(){
// 'mammals' constructor - My 'empirical' 'class'...
} 
   mammal.count = 0; // To keep track of the zoo I've created. No subclass can access this property. It's a 'static' property

   // I could have declared this 'method' inside of my constructor
   // with an anonymous function attached to (this.prototype.breathe).

    mammal.track = function (){
        this.count++;
    }

    mammal.prototype.breathe = function(){
        alert("Inhale... Exhale...");
    }

function cat(){
// 'cat' constructor
}

// All cats shall now become a type of mammal
cat.prototype = new mammal();

cat.prototype = function(){
// This anonymous function is the REAL constructor for my 'cat' 'superclass'
}

    cat.prototype.meow = function(){
        alert("Meow!");
    }

function lion(){
// The king of jungle...
// I can keep track of the number of 'mammal' instances I create here
mammal.track();
}

// All lions are cats, afterall...
lion.prototype = new cat();
// Also note that I have no plans to extend the lion class.
// I have no need of a class below the 'idea' of a lion 

    lion.name = "Kitty"; // :}

    // Here's where I get confused...
    // I can set (lion.name) via instances, can't call (lion.pounce), but (lion.prototype.roar) works all day long! o_0
    lion.pounce = function(){
        alert(this.name+" pounces...")
    }

    lion.prototype.roar = function(){
        alert(this.name+" doesn't meow, he ROOOAAARS!"); 
    }

// With these constructs in place, I can now script...
$(document).ready(function(){

      var rory = new lion();    
      var napoleon = new lion();

      alert("We have "+mammal.count+" mammals running about");

          // This is 'Rory'...
          rory.name = 'Rory'; // Respect the pun...
          rory.roar();

          // This is 'Napoleon'...
          napoleon.name = 'Napoleon';
          napoleon.breathe(); // Napoleon can't breathe... he didn't inherit mammal.prototype.breathe(), for some reason
          napoleon.roar(); // How am I able to set (lion.name), but not call lion.pounce()?
          napoleon.pounce();

});

You were right of course, every class in my chain right up to the creation of the final instance(s), is a prototype function. But why does (lion.name) work but not (lion.prototype.name). Conversely, why might lion.prototype.pounce() work, when lion.pounce() borks?

Napoleon and Rory are both Lions afterall...

I have loads more Javascript questions... It's a very strange language... ;)

Charlie