通过设置__proto__将Node.js / Javascript方法引入现有对象

TL; DR – 可以通过设置__proto__属性来实现类似mixin的行为吗?

我有一个对象列表(从某个外部源获取),它们都具有相同的一组属性(比如_name )。 我想为它们中的每一个添加一些常用的方法(比如, nameLen() ,它返回_name属性的长度)。 这是一个办法:

 // In reality this list of docs is generated by the DB driver: var docs = [ { _name: 'some name' }, { _name: 'some other name' } ] // Now, I want to introduce a method to each doc... docs.forEach(function(doc) { doc.nameLen = function() { return this._name.length; } }); 

然后我意识到我可以通过设置每个doc的__proto__属性来实现类似的行为:

 // In reality this list of docs is generated by the DB driver: var docs = [ { _name: 'some name' }, { _name: 'some other name' } ] // Now, I want to introduce a method to each doc... var myMixin = { nameLen: function() { return this._name.length; } }; docs.forEach(function(doc) { doc.__proto__ = myMixin; // <-- Use myMixin as the prototype }); 

假设所有我想要添加的是方法,而不是状态,这似乎是一个更优雅的解决scheme:(一)节省空间; (b)我可以稍后向myMixin添加方法,他们将立即在所有文档中提供。

另一方面,摆弄__proto__似乎有点冒险,但我不确定,因此我的问题:

通过更改__proto__属性将方法引入预先存在的对象是否安全?

明确的阶级而不是特设的内联原生变化可能会更好。

 var Doc = require( "./doc.js" ); //FIXME configure your driver/schema so that Doc objects //are returned in the first place var docs = docs.map(function(v) { return new Doc(v._name); }); //Done 

Doc.js:

 module.exports = (function() { var method = Doc.prototype; function Doc( name ) { this._name = name; } method.nameLen = function() { return this._name.length; }; return Doc; })(); 

但是,是的,即使它看起来不太可维护,也是安全的。