2

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; }
});

__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
});  

假设我想添加的只是方法而不是说明这似乎是一个更优雅的解决方案:(a)节省空间;(b) 我可以稍后添加方法myMixin,它们将立即在所有文档中可用。

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

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

4

1 回答 1

3

使用显式类而不是临时内联原型更改可能会更好。

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

文档.js:

module.exports = (function() {
    var method = Doc.prototype;

    function Doc( name ) {
        this._name = name;
    }

    method.nameLen = function() {
        return this._name.length;
    };

    return Doc;
})();

但是,是的,即使它看起来对我来说不太容易维护,这也是安全的。

于 2013-08-16T18:47:34.023 回答