インスタンス化するときにユーザーがオブジェクトを提供できるようにし、デフォルトをプロトタイプに入れます。また、構成機能を提供することもできます。これにより、(現在または将来) キー/値を検証し、インスタンス化後にユーザーが構成を設定できるようになります。
// Module
var Mod = module.exports = function Mod (opts) {
opts = (opts === Object(opts)) ? opts : {};
// This allows users to instanciate without the `new` keyword
if (! (this instanceof Mod)) {
return new Mod(opts);
}
// Copy user provided configs to this.config
for (var key in opts) if ({}.hasOwnProperty.call(opts, key)) {
this.config[key] = opts[key];
}
};
Mod.prototype.config = {
foo : 'foo',
bar : 'bar'
};
Mod.prototype.configure = function configure (key, val) {
this.config[key] = val;
return this;
};
// Usage
const Mod = require('/path/to/mod');
var i1 = new Mod;
var i2 = Mod();
var i3 = new Mod({
foo: 'bar'
});
var i4 = Mod({
foo: 'bar'
});
i4.configure('bar', 'baz');
var i5 = (new Mod).configure('bar', 'baz');
編集
Jake Sellers がコメントで指摘したように、これは CommonJS モジュールの標準 API パターンではありません。より良い解決策は、作成しているオブジェクトを返す関数をエクスポートすることです。
さらに重要なことは、構成をプロトタイプに入れることは絶対に勧めないということです。これを行うと、構成オブジェクトがすべての子で共有されます。そのため、それに対する変更はすべての子にも影響します。残念なことに、このくだらないことを書いたとき、私は初心者ではありませんでした。ありがとうジェイク;)
より良い実装:
// Keep defaults private
var defaults = {
foo : 'foo',
bar : 'bar'
};
// Construct
var Mod = function Mod (opts) {
opts = (opts === Object(opts)) ? opts : {};
// This allows users to instanciate without the `new` keyword
if (! (this instanceof Mod)) {
return new Mod(opts);
}
this.config = {};
// Copy user provided configs to this.config or set to default
for (var key in defaults) if (defaults.hasOwnProperty(key)) {
if ({}.hasOwnProperty.call(opts, key)) {
this.config[key] = opts[key];
}
else {
this.config[key] = defaults[key];
}
}
};
// Let the user update configuration post-instanciation
Mod.prototype.configure = function configure (key, val) {
this.config[key] = val;
return this;
};
// Export a function that creates the object
exports.createMod = function createMod (opts) {
return new Mod(opts);
};
// Export the constructor so user is able to derive from it
// or check instanceof
exports.Mod = Mod;
// USAGE
var mod = require('/path/to/mod');
var i1 = mod.createMod({ foo : 'bar' });
i1.configure('bar', 'baz');