我会考虑两种解决方案,具体取决于我是想为每个文件定义一个方法还是将多个相关方法分组到一个文件中。
每个文件一个方法
从这样的目录结构开始:
foo/
foo.a.js
foo.b.js
index.js
main.js
Foo 的其中一种方法可能如下所示:
// foo/foo.a.js
module.exports = function() {
console.log('Method A');
};
其他方法可以用类似的方式定义。 Foo 本身可以这样定义:
// foo/index.js
function Foo() { }
Foo.prototype.methodA = require('./foo.a');
Foo.prototype.methodB = require('./foo.b');
module.exports = Foo;
现在我们可以像这样使用Foo:
// main.js
var Foo = require('./foo');
var foo = new Foo();
foo.methodA(); // 'Method A'
foo.methodB(); // 'Method B'
与您自己的解决方案相比,此解决方案的一个优点是Foo 的所有方法都在一个地方声明,即在foo/index.js 中,但在其他地方定义。看一个文件,Foo 有哪些方法,一目了然,而没有它们实现的所有混乱。
每个文件有多种方法
在这种情况下,我倾向于使用mixin 模式。目录结构如下:
/foo
bar.js
baz.js
index.js
/utils
extend.js
mixin.js
main.js
从一个扩展一个对象到另一个对象的函数开始,包括 getter/setter 并保持相同的 property descriptor。
// utils/extend.js
module.exports = function extend(target, source) {
var names = Object.getOwnPropertyNames(source);
var len = names.length;
for (var i = 0; i < len; i++) {
var name = names[i];
var descriptor = Object.getOwnPropertyDescriptor(source, name);
Object.defineProperty(target, name, descriptor);
}
};
mixin 只是对两个对象的原型执行此操作:
// utils/mixin.js
var extend = require('./extend');
module.exports = function mixin(target, source) {
extend(target.prototype, source.prototype);
};
现在我们可以像这样定义Bar 基类:
// foo/bar.js
function Bar(a, b) {
this.a = a;
this.b = b;
}
Bar.prototype.methodA = function() {
console.log(this.a);
};
Bar.prototype.methodB = function() {
console.log(this.b);
};
module.exports = Bar;
Baz 可以类似地定义。然后Foo,扩展两者,可以这样定义:
// foo/index.js
var Bar = require('./bar');
var Baz = require('./baz');
var mixin = require('../utils/mixin');
function Foo(a, b, c, d) {
Bar.call(this, a, b);
Baz.call(this, c, d);
}
mixin(Foo, Bar);
mixin(Foo, Baz);
module.exports = Foo;
我们可以这样使用它:
// main.js
var Foo = require('./foo');
var foo = new Foo('one', 'two', 'three', 'four');
foo.methodA(); // 'one'
foo.methodB(); // 'two'
foo.methodC(); // 'three'
foo.methodD(); // 'four'
这种方法的一个优点是我们可以自己使用Bar 或Baz 或扩展其他类。此外,每个都有自己的构造函数这一事实让我们可以在定义它们的文件中声明它们的依赖关系,而不是必须记住在 Foo 构造函数中分配 this.a 属性。