简体   繁体   中英

Can you access prototype properties within prototype functions?

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.

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

在此处输入图片说明

JSFiddle to demonstrate original question.

 // 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, ie

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM