通过设置__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; })();
但是,是的,即使它看起来不太可维护,也是安全的。