在快速路由处理程序中暂时覆盖原型方法是否安全?

我有一个有很多Date实例的对象。 该对象然后转换成JSON ,并返回:

 router.post('/', function () { // Some code that returns the object res.status(200).json(object); }); 

我需要改变所有的Date对象如何转换为JSON,所以我想这样做:

 router.post('/', function() { var originalToJSON = Date.prototype.toJSON; Date.prototype.toJSON = function() { return moment(this).format(...); // some formatting function } res.status(200).json(object); Date.prototype.toJSON = originalToJSON; }); 

我意识到这是一个可怕的做法,但我很好奇它的含义。 由于我正好将对象转换为JSON后将Date.prototype.toJSON恢复为原始状态,是否有可能同时res.status(200).json(object)请求正在运行,并且被覆盖Date.prototype.toJSON

代码的其他部分不会使用已更改的JSON方法,因为代码运行完成,并且不会在JSON方法的这两个更改之间产生或等待,但存在代码不会使用你改变的方法 – 这实际上取决于res.json()的实现,虽然它现在可以工作,但是如果Express的内部实现发生变化,并且依赖于它不会改变的话,将来可能会停止工作具有将来破裂风险的抽象。

你可以在这里做其他的事情:

  1. 您可以使用自己的自定义对象的date,并将其转换,但是你想要的。
  2. 您可以使用您自己的准备JSON的function,而不是依靠内置的快速function
  3. 您可以使用JSON.stringify的replacer参数来获得您的优势
  4. 您可以使用整个对象的自定义对象进行分离,而不仅仅是数字1中的date

对于数字3,请参阅: https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

replacer参数可以是一个函数也可以是一个数组。 作为一个函数,它需要两个参数,键和值被串行化。 提供密钥的对象是作为替代者的这个参数提供的。 最初,它被一个空键代表被串化的对象调用,然后被对象或数组上的每个属性被串行化。 […]如果您返回一个string,则将该string添加到JSONstring时将用作该属性的值。

在你的特定情况下,replace者可以只是返回格式化的date,但是你想要的,并返回一切不变。 JSON.stringify()JSON.stringify()参数是专门针对这种情况创build的。

在这种情况下,一切都是同步的,所以一次就能执行。 因此,这样做应该是安全的。

然而,搞乱原型通常是一个糟糕的主意,特别是当你的问题有更简单的解决scheme时:

 function toJSON(input) { if(typeof input === 'date') { return moment(input).format(); } else if(typeof input === 'object') { let o = {}; Object.keys(input).map((key) => { o[key] = toJSON(input[key]); }); return o; } else { return input; } } router.post('/', function() { var originalToJSON = Date.prototype.toJSON; Date.prototype.toJSON = function() { return moment(this).format(...); // some formatting function } res.status(200).json(toJSON(object)); Date.prototype.toJSON = originalToJSON; });