我有一个Javascript类(在ES6中)已经很长了。为了更好地组织它,我想将它分成2或3个不同的文件。我怎么能这样做?
目前它在一个文件中看起来像这样:
class foo extends bar {
constructor(a, b) {} // Put in file 1
methodA(a, b) {} // Put in file 1
methodB(a, b) {} // Put in file 2
methodC(a, b) {} // Put in file 2
}
谢谢!
答案 0 :(得分:5)
创建课程时
class Foo extends Bar {
constructor(a, b) {
}
}
稍后您可以通过分配原型来为此类添加方法:
// methodA(a, b) in class Foo
Foo.prototype.methodA = function(a, b) {
// do whatever...
}
您也可以通过直接分配给类来添加静态方法:
// static staticMethod(a, b) in class Foo
Foo.staticMethod = function(a, b) {
// do whatever...
}
您可以将这些函数放在不同的文件中,只要它们在声明了类之后运行。
但是,构造函数必须始终成为类声明的一部分(您无法将其移动到另一个文件中)。此外,您需要确保定义类方法的文件在使用之前运行。
答案 1 :(得分:3)
我选择将所有privte变量/函数包含在一个称为private的对象中,并将其作为第一个参数传递给外部函数。
通过这种方式,他们可以访问局部变量/函数。
请注意,他们也隐式访问'this'
文件:person.js
const { PersonGetAge, PersonSetAge } = require('./person_age_functions.js');
exports.Person = function () {
// use privates to store all private variables and functions
let privates={ }
// delegate getAge to PersonGetAge in an external file
// pass this,privates,args
this.getAge=function(...args) {
return PersonGetAge.apply(this,[privates].concat(args));
}
// delegate setAge to PersonSetAge in an external file
// pass this,privates,args
this.setAge=function(...args) {
return PersonSetAge.apply(this,[privates].concat(args));
}
}
文件:person_age_functions.js
exports.PersonGetAge =function(privates)
{
// note: can use 'this' if requires
return privates.age;
}
exports.PersonSetAge =function(privates,age)
{
// note: can use 'this' if requires
privates.age=age;
}
文件:main.js
const { Person } = require('./person.js');
let me = new Person();
me.setAge(17);
console.log(`I'm ${me.getAge()} years old`);
输出:
I'm 17 years old
请注意,为了不重复person.js上的代码,可以在循环中分配所有功能。
例如
person.js选项2
const { PersonGetAge, PersonSetAge } = require('./person_age_functions.js');
exports.Person = function () {
// use privates to store all private variables and functions
let privates={ }
{
// assign all external functions
let funcMappings={
getAge:PersonGetAge,
setAge:PersonSetAge
};
for (const local of Object.keys(funcMappings))
{
this[local]=function(...args) {
return funcMappings[local].apply(this,[privates].concat(args));
}
}
}
}
答案 2 :(得分:0)
这是我的解决方案。它:
.bind()
进行,而不使用prototype
。首先,将其放置在globals文件中或作为第一个<script>
标签等。
BindToClass(functionsObject, thisClass) {
for (let [ functionKey, functionValue ] of Object.entries(functionsObject)) {
thisClass[functionKey] = functionValue.bind(thisClass);
}
}
这将循环遍历一个对象,并将该对象中的每个函数按其名称分配并绑定到该类。 .bind()
是this
上下文的缩写,因此就像在类中一样。
然后将您的函数从类中提取到一个单独的文件中,例如:
//Use this if you're using NodeJS/Webpack. If you're using regular modules,
//use `export` or `export default` instead of `module.exports`.
//If you're not using modules at all, you'll need to map this to some global
//variable or singleton class/object.
module.exports = {
myFunction: function() {
//...
},
myOtherFunction: function() {
//...
}
};
最后,需要一个单独的文件并在该类的 BindToClass
函数中像这样调用constructor() {}
,然后再执行可能依赖于这些分离函数的任何其他代码:
//If not using modules, use your global variable or singleton class/object instead.
let splitFunctions = require('./SplitFunctions');
class MySplitClass {
constructor() {
BindToClass(splitFunctions, this);
}
}
然后,其余代码将与那些函数以类开头的情况保持相同:
let msc = new MySplitClass();
msc.myFunction();
msc.myOtherFunction();
同样,由于直到真正调用了函数 之前,什么都没有发生,所以只要首先调用BindToClass()
,就不必担心函数的顺序。与往常一样,类文件内外的每个函数仍可以访问该类内的任何属性或函数。
答案 3 :(得分:0)
您可以像这样将mixins添加到YourClass:
class YourClass {
ownProp = 'prop'
}
class Extension {
extendedMethod() {
return `extended ${this.ownProp}`
}
}
addMixins(YourClass, Extension /*, Extension2, Extension3 */)
console.log('Extended method:', (new YourClass()).extendedMethod())
function addMixins() {
var cls, mixin, arg
cls = arguments[0].prototype
for(arg = 1; arg < arguments.length; ++ arg) {
mixin = arguments[arg].prototype
Object.getOwnPropertyNames(mixin).forEach(prop => {
if (prop == 'constructor') return
if (Object.getOwnPropertyNames(cls).includes(prop))
throw(`Class ${cls.constructor.name} already has field ${prop}, can't mixin ${mixin.constructor.name}`)
cls[prop] = mixin[prop]
})
}
}
答案 4 :(得分:0)
我的解决方案类似于by Erez(在文件中声明方法,然后在构造函数中将方法赋值给this
),但是
.apply()
的层 - 函数直接插入到实例中C.js
class C {
constructor() {
this.x = 1;
this.addToX = require('./addToX');
this.incX = require('./incX');
}
}
addToX.js
function addToX(val) {
this.x += val;
return this.x;
}
module.exports = addToX;
incX.js
function incX() {
return this.addToX(1);
}
module.exports = incX;
请注意,此语法目前为 Stage 3 proposal。
但它适用于 Node.js 14——我关心的平台。
C.js
class C {
x = 1;
addToX = require('./addToX');
incX = require('./incX');
}
const c = new C();
console.log('c.incX()', c.incX());
console.log('c.incX()', c.incX());
答案 5 :(得分:-2)
我有一个Javascript类(在ES6中)已经很长了。为了更好地组织它,我想将它分成2或3个不同的文件。我怎么能这样做?
如果你不想要处理程序,你必须在文件1中声明该类,使其成为全局类(就像我之前评论过的那样......之前),并在其他文件中可以(重新)在这个类的原型对象中指定属性(这是一个函数)。
如果您要退出课程块表达,那就是事实。