将侦听器添加到Object prototype

时间:2016-07-30 10:37:58

标签: javascript node.js prototype

我正在运行一个带有ws的WebSocket服务器,并且正在尝试根据它们是否为JSON来分割传入的消息。

function determineJSON(m) {
    try         { return ['json', JSON.parse(m)] }
    catch (err) { return ['not-json', m] }
}

wss.on('connection', ws => {
    ws.on('message', m => {
        // Emit to 'json' and 'not-json' as appropriate
        if (ws.listenerCount('json') + ws.listenerCount('not-json') > 0) {
            ws.emit(...determineJSON(m))
        }
    })
    .on('json', j => { ... })
    .on('not-json', m => { ... })
})

代码效果很好,但我想知道如何将.on('message', ...)侦听器添加到WS类,以便所有新的WS对象都可以使用它。我尝试了WS.prototype.on('message', ...),但似乎没有做任何事情。

2 个答案:

答案 0 :(得分:1)

实际上你想要创建具有预定义状态的WS实例吗?

出于这个目的,我建议你创建一个可以为你处理它的工厂。

WsFactory.create = function () {
    var ws = new WS(); //or whatever you use for creating
    ws.on(...);
    return ws;
}

你会避免改变原型,并且会得到你想要的东西。

答案 1 :(得分:0)

嗯,我不是修改原型的忠实粉丝,所以你可以这样做:

function determineJSON(m) {
    try         { return ['json', JSON.parse(m)] }
    catch (err) { return ['not-json', m] }
}

function decorateWS(ws) {
    return ws.on('message', m => {
        // Emit to 'json' and 'not-json' as appropriate
        if (ws.listenerCount('json') + ws.listenerCount('not-json') > 0) {
            ws.emit(...determineJSON(m))
        }
    })
}

wss.on('connection', ws => {
    decorateWS(ws).on('json', j => { ... })
                  .on('not-json', m => { ... })
})

无论如何,如果您想修改类本身,您可能需要执行以下操作:

let origConstructor = ws.prototype.constructor;
WS.prototype.constructor = () => {
   origConstructor.apply( this, arguments );
   const ws = this;
   this.on('message', m => {
       // Emit to 'json' and 'not-json' as appropriate
       if (ws.listenerCount('json') + ws.listenerCount('not-json') > 0) {
           ws.emit(...determineJSON(m))
       }  
     })
}

无论如何,我认为这可能会产生副作用。因此,装饰方法看起来更好,更易于维护。