Javascript 您可以访问原型函数中的原型属性吗?

Javascript 您可以访问原型函数中的原型属性吗?,javascript,prototype,Javascript,Prototype,如果我声明这样的类: var Foo = function() {}; Foo.prototype.bar = ""; Foo.prototype.setBar = function( value ) { this.bar = value; } 并向其添加如下属性: var Foo = function() {}; Foo.prototype.bar = ""; Foo.prototype.setBar = function( value ) { this.bar = va

如果我声明这样的类:

var Foo = function() {};
Foo.prototype.bar = "";
Foo.prototype.setBar = function( value ) {
   this.bar = value;
}
并向其添加如下属性:

var Foo = function() {};
Foo.prototype.bar = "";
Foo.prototype.setBar = function( value ) {
   this.bar = value;
}
为什么我不能像这样访问该属性:

var Foo = function() {};
Foo.prototype.bar = "";
Foo.prototype.setBar = function( value ) {
   this.bar = value;
}
在我的代码中,在
Foo.prototype.SetBar
的范围内没有
Foo.prototype.bar
。此.bar显示未定义

更新

好吧,也许我应该更具体一点,因为出于某种原因,我的代码没有运行

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 );
}
现在在
JSocketServer.prototype.handleSocket
中,我试图为
this.socketPool
分配一个键和值,这意味着
this.socketPool
未定义。现在根据我的理解和你们所说的,这不应该

更新


这里是我的代码的JS小提琴。我有两个类JSocketServer和JSocket,它们被底部的应用程序使用。

是的,但只有在检索值时才能使用。设置该值将创建实例属性。如果指定实例属性,将返回该属性而不是原型值。这意味着您可以:

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
下面是一个基于以下站点的圆圈的示意图和示例


演示原始问题。

可以,但只能在检索值时进行。设置该值将创建实例属性。如果指定实例属性,将返回该属性而不是原型值。这意味着您可以:

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
下面是一个基于以下站点的圆圈的示意图和示例

演示原始问题

是使代码无法工作的部分。将用继承自
EventEmitter
的新空对象覆盖
JSocketServer
(和
JSocket
)的
.prototype

仅在继承后才对原型对象进行赋值

// 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 = "";

顺便说一句,对于静态类属性,您最好(更好?)将它们直接放在构造函数上,而不是放在原型上,即

JSocketServer.socketPool = {};
JSocketServer.socketMap = {};
然后始终使用这个完整的限定名显式引用它们,而不是作为(继承的)实例属性

是使代码无法工作的部分。将用继承自
EventEmitter
的新空对象覆盖
JSocketServer
(和
JSocket
)的
.prototype

仅在继承后才对原型对象进行赋值

// 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 = "";

顺便说一句,对于静态类属性,您最好(更好?)将它们直接放在构造函数上,而不是放在原型上,即

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

然后始终使用此全名明确引用它们,而不是作为(继承的)实例属性。

请注意,
bar
setBar
都是实例之间的共享属性(因为您在
原型上设置了它们)…
this.bar
不同于
Foo.prototype.bar
@Ian:虽然如果没有在实例上定义this.bar,它会被原型破坏。@Ian我不太清楚你的意思。如果运行OP拥有的代码,则执行以下操作:
var foo=new foo();f、 挫折(“asdf”)
,…
foo.bar
等于
“asdf”
,而
foo.prototype.bar
仍然是
@Ian+Ian这很让人困惑:|@Ian-(IanW说):这是很让人困惑的评论!是的,在原型链的上游是我强调的。我已经充实了我的答案,并添加了一个链接来尝试说明这一点。请注意,
bar
setBar
都是实例之间的共享属性(因为您在
原型上设置了它们)…
this.bar
不同于
Foo.prototype.bar
@Ian:虽然如果没有在实例上定义this.bar,它会被原型破坏。@Ian我不太清楚你的意思。如果运行OP拥有的代码,则执行以下操作:
var foo=new foo();f、 挫折(“asdf”)
,…
foo.bar
等于
“asdf”
,而
foo.prototype.bar
仍然是
@Ian+Ian这很让人困惑:|@Ian-(IanW说):这是很让人困惑的评论!是的,在原型链的上游是我强调的。我已经充实了我的答案,并添加了一个链接,试图说明这一点。为什么要投反对票?我的回答在某种程度上不正确吗?如果是这样,请告诉我:)我不知道谁会投反对票。这是我得到的最好的答案之一。我已经更新了我的问题,使之更加具体,因为我仍然不知道为什么它不会运行。我知道我可以执行“this.socketPool={}”在构造函数内部,但我认为属性与函数的工作原理相同,因为如果我使用原型声明它们,它们将在编译时初始化,而不是在运行时初始化。谢谢您的帮助。答案确实在完整的代码中。我对你的评论投了赞成票,并对你的努力作出了回答。为什么投反对票?我的回答在某种程度上不正确吗?如果是这样,请告诉我:)我不知道谁会投反对票。这是我得到的最好的答案之一。我已经更新了我的问题,使之更加具体,因为我仍然不知道为什么它不会运行。我知道我可以执行“this.socketPool={}”在构造函数内部,但我认为属性与函数的工作原理相同,因为如果我使用原型声明它们,它们将在编译时初始化,而不是在运行时初始化。谢谢您的帮助。答案确实在完整的代码中。我对你的评论投了赞成票,并对你的努力作出了回答!非常感谢。你能详细说明一下这样做如何更好?如果我有多个JSocketServer实例,这是否有效?函数也可以这样声明吗?正如您所说,它们是类本身的静态属性。它们与实例无关。是的,您可以将(“declare”是错误的术语)任何值指定为的属性