【问题标题】:JSON.stringify fails on a newly created object (node, javascript)JSON.stringify 在新创建的对象(节点、javascript)上失败
【发布时间】:2013-09-14 14:01:33
【问题描述】:

好的,这个问题一定很简单,但我刚开始学习节点。我也是javascript新手,所以,请不要留情指出下面的错误方向。

特别是我有两个文件:

  • 一个类可以在不同的端口创建一些从属服务器
  • 另一个是生成从属的“主”文件

当我试图打印出我刚刚初始化的内容时,我得到了两个奇怪的错误:

  • connections 属性已弃用。使用 getConnections() 方法,然后
  • 当我尝试在新对象中应用 JSON.stringify 时崩溃(将循环结构转换为 JSON)

“slave.js”文件中的从属代码:

var http = require ("http");

function Slave () {
}

Slave.prototype.ID           = undefined;
Slave.prototype.coordinator  = false;
Slave.prototype.httpServer   = undefined;
Slave.prototype.thePort      = undefined;

Slave.prototype.isCoordinator = function () { return this.coordinator; }

/*****************************************************************/

function handle_incoming_request (req, res) {
    console.log("INCOMING REQUEST: " + req.method + " " + req.url);
    res.writeHead (200, { "Content-Type" : "application/json" });
    res.end( JSON.stringify({ "error" : null }) + "\n" );
}

exports.createSlave = function (id, coordinatorK, port) {
    var temp         = new Slave ();
    temp.ID          = id;
    temp.coordinator = coordinatorK;
    temp.thePort     = port;
    temp.httpServer  = http.createServer(handle_incoming_request);
    temp.httpServer.listen (temp.thePort);
    console.log ("Slave (" + (temp.isCoordinator() ? "coordinator" : "regular") + ") with ID " + temp.ID + " is listening to port " + temp.thePort);
    console.log ("--------------------------------------------");

    return temp;
}

现在,主文件。

var http   = require ("http");
var url    = require ("url");
var a      = require ("./slave.js");

var i, temp;
var myArray = new Array ();

for (i = 0; i < 4; i++) {
    var newID = i + 1;
    var newPort = 8000 + i + 1;
    var coordinatorIndicator = false;

    if ((i % 4) == 0) {
        coordinatorIndicator = true; // Say, this is going to be a coordinator
    }

    temp = a.createSlave (newID, coordinatorIndicator, newPort);
    console.log ("New slave is  : " + temp);
    console.log ("Stringified is: " + JSON.stringify(temp));

    myArray.push(temp);
}

【问题讨论】:

  • 你不能只对任何旧对象进行字符串化。

标签: javascript json node.js stringify


【解决方案1】:

您正在尝试对http.createServer(...) 的结果进行字符串化。这不是您想要做的,所以当您创建该属性时,通过使用Object.defineProperty() 定义它使其不可枚举。

exports.createSlave = function (id, coordinatorK, port) {
    var temp         = new Slave ();
    temp.ID          = id;
    temp.coordinator = coordinatorK;
    temp.thePort     = port;

    Object.defineProperty(temp, "httpServer", {
        value: http.createServer(handle_incoming_request),
        enumerable: false, // this is actually the default, so you could remove it
        configurable: true,
        writeable: true
    });
    temp.httpServer.listen (temp.thePort);
    return temp;
}

这样JSON.stringify 将无法达到固化其对象枚举的属性。

【讨论】:

  • 这个确实可以工作,只是稍作改动:命令 temp.httpServer.listen (temp.thePort);应该在 Object.defineProperty(...) 之后。请更改此顺序。在我接受之前,我将再等几分钟,看看是否还有其他答案。感谢您的宝贵时间!
  • 当然,我改了。编辑的时候没注意顺序。
【解决方案2】:

问题是temp 对象的属性httpServer 具有循环引用。您可以使用Ecmascript5 属性定义将其设置为不可枚举,如上一个答案中所述,或者您可以使用JSON.stringify 的替换函数对其进行自定义以不将httpServer 属性字符串化。

   console.log ("Stringified is: " + JSON.stringify(temp, function(key, value){
         if(key === 'httpServer') return undefined;
        return value;
    }));

【讨论】:

  • 感谢 PSL 的宝贵时间和替代解释。我很感激。我在 user2736012 上授予此权限,因为他的声誉较低。
  • @MightyMouse 欢迎您。理想情况下,在节点世界中,您应该使用 EcmaScript5 定义,这将使其成为定义对象的更标准方式。因为它已经发布了,所以我只是提供了一个替代方案..您选择了正确的答案.. :)
猜你喜欢
  • 2011-07-16
  • 2017-02-25
  • 1970-01-01
  • 2019-11-13
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多