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

Node.js/Javascript introducing methods to existing object by setting __proto__

本文关键字:对象 方法 proto Javascript Node 设置 js      更新时间:2023-09-26

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__属性,将方法引入已有对象是否安全?

最好只是有显式的类,而不是临时的内联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;
})();

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