0

If I declare a class like this:

var Foo = function() {}; 

And add properties to it like this:

Foo.prototype.bar = ""; 

Why can't I access the property like this:

Foo.prototype.setBar = function( value ) { this.bar = value; } 

In my code I don't have Foo.prototype.bar in scope of Foo.prototype.SetBar. this.bar is showing undefined.

UPDATE

Ok maybe I should be a little more specific since for some reason my code is not running.

var JSocketServer = function( options, callback ) { if( typeof(options) != "object" ) { callback("Invalid object passed for options"); return; } if( typeof(options.port) != "number" ) { callback("Must specify a port number in options"); return; } // Hook up Event Emitter Functionality mevents.EventEmitter.call(this); this.initServer( options, callback ); }; // Set up static class properties JSocketServer.prototype.socketPool = {}; JSocketServer.prototype.socketMap = {}; // Inherit from EventEmitter mutil.inherits(JSocketServer, mevents.EventEmitter); JSocketServer.prototype.initServer = function( options, callback ) { // Hook up raw tcp server var jserver = this; var server = mnet.createServer( function( socket ) { jserver.handleSocket( socket, callback ); }); server.listen(options.port, function() { console.log("Socket Server is bound"); }) this.serverListener( server ) } JSocketServer.prototype.handleSocket = function( socket, callback ) { var jsocketServer = this; var jsocket = new mjsocket(socket); console.log("Socket: "+jsocket.socketID+" connected"); this.socketPool[jsocket.socketID] = jsocket; jsocket.on("data", function( data ) { // Add socket id to socket map jsocketServer.socketMap[jsocket.moduleID] = jsocket.socketID; }); jsocket.on("close", function(err) { jsocketServer.removeSocket(jsocket.socketID); }); // Callback with JSocket callback( undefined, jsocket ); } 

Now inside JSocketServer.prototype.handleSocket where I'm trying to assign a key and value to this.socketPool, it's saying that this.socketPool is undefined. Now from my understanding and what you guys are saying, this shouldn't be.

UPDATE

Here's a JS Fiddle of my code http://jsfiddle.net/bZrtn/. I have 2 classes JSocketServer and JSocket and they're being used by the APP at the bottom.

15
  • 2
    Note that both bar and setBar are shared properties between instances (since you set them on the prototype)...this.bar is different than Foo.prototype.bar Commented Jun 16, 2014 at 18:23
  • 1
    @Ian: Althought this.bar will fall through to the prototype if it hasn't been defined on the instance. Commented Jun 16, 2014 at 18:27
  • 1
    @Ian I'm not exactly sure what you mean. If you run the code the OP has, then do this: var foo = new Foo(); f.setBar("asdf");,...foo.bar equals "asdf", and Foo.prototype.bar is still "" Commented Jun 16, 2014 at 18:32
  • 2
    @Ian+Ian This is confusing :| Commented Jun 16, 2014 at 18:33
  • 2
    @Ian - (IanW says): This is quite confusing commenting! Yeah going up the prototype chain is what I was highlighting. I've fleshed out my answer and added a link to try and illustrate this. Commented Jun 16, 2014 at 18:35

2 Answers 2

4

Yes you can but only when retrieving the value. Setting the value will create an instance propety. If you specify an instance property it will be returned instead of the prototype value. This means you could have:

Foo.prototype.radius = 5; Foo.prototype.diameter = function() { return this.radius * 2; }; var circle = new Foo(); console.log(circle.diameter()); // prints 10 circle.radius = 10; console.log(circle.diameter()); // prints 20 just for this instance 

Here's a diagram that illustrates and an example based on a circle from the following site http://docstore.mik.ua/orelly/webprog/jscript/ch08_04.htm

enter image description here

JSFiddle to demonstrate original question.

Sign up to request clarification or add additional context in comments.

4 Comments

Why the downvote? Is my answer incorrect in someway? If so please enlighten me :)
I don't know who would downvote that. One of the best answers I've ever gotten. I've updated my question to be more specific since I still can't figure out why it won't run.
I know I could do "this.socketPool = {}" inside the constructor but I thought that properties worked the same as functions in that if I declare them with prototype they get initialized at compile time instead of initialized at runtime.
Thanks for your help. The answer was indeed in the full code. I upvoted all your comments and answer for your efforts
2
// Set up static class properties JSocketServer.prototype.socketPool = {}; JSocketServer.prototype.socketMap = {}; // Inherit from EventEmitter mutil.inherits(JSocketServer, mevents.EventEmitter); 

and

// Set static class properties JSocket.prototype.moduleID = ""; JSocket.prototype.dataArray = []; JSocket.prototype.dataString = ""; // Inherit from EventEmitter mutil.inherits(JSocket, mevents.EventEmitter); 

are the parts that make your code not work. utils.inherit will overwrite the .prototype of JSocketServer (and JSocket) with a new, empty object that inherits from EventEmitter.

Do the assignments to the prototype object only after you have inherited!

// Inherit from EventEmitter first mutil.inherits(JSocketServer, mevents.EventEmitter); // then set up static class properties JSocketServer.prototype.socketPool = {}; JSocketServer.prototype.socketMap = {}; … // Inherit from EventEmitter first mutil.inherits(JSocket, mevents.EventEmitter); // then set static class properties JSocket.prototype.moduleID = ""; JSocket.prototype.dataArray = []; JSocket.prototype.dataString = ""; 

Btw, for static class properties you might as well (better?) put them on the constructor directly instead of the prototype, i.e.

JSocketServer.socketPool = {}; JSocketServer.socketMap = {}; 

and then always reference them explicitly with this full-qualifed name, instead of as (inherited) instance properties.

2 Comments

Awesome! Thanks so much. Can you elaborate on how declaring them is better that way? Does this work if I have multiple instances of JSocketServer? Can functions be declared like that as well?
As you say, they are static properties of the class itself. They have nothing to do with instances. Yes, you can assign ("declare" is the wrong term) any values as properties of the constructor function, including functions.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.