Tho*_*mas 9 javascript oop ecmascript-6
我有一个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
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
创建课程时
class Foo extends Bar {
constructor(a, b) {
}
}
Run Code Online (Sandbox Code Playgroud)
您可以稍后通过分配给其原型为该类添加方法:
// methodA(a, b) in class Foo
Foo.prototype.methodA = function(a, b) {
// do whatever...
}
Run Code Online (Sandbox Code Playgroud)
您还可以通过直接分配给类来类似地添加静态方法:
// static staticMethod(a, b) in class Foo
Foo.staticMethod = function(a, b) {
// do whatever...
}
Run Code Online (Sandbox Code Playgroud)
您可以将这些函数放在不同的文件中,只要它们在类声明后运行即可。
但是,构造函数必须始终是类声明的一部分(不能将其移动到另一个文件中)。此外,您需要确保在使用定义类方法的文件之前运行它们。
这是我的解决方案。它:
.bind()ing, no prototype。(编辑:实际上,请参阅评论以了解更多信息,这可能并不可取。)首先,将其放入全局文件中或作为第一个<script>标签等:
BindToClass(functionsObject, thisClass) {
for (let [ functionKey, functionValue ] of Object.entries(functionsObject)) {
thisClass[functionKey] = functionValue.bind(thisClass);
}
}
Run Code Online (Sandbox Code Playgroud)
它循环遍历一个对象,并按名称将该对象中的每个函数分配并绑定到该类。这.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() {
//...
}
};
Run Code Online (Sandbox Code Playgroud)
最后,在可能依赖这些分离函数的任何其他代码之前,需要单独的文件并在类的函数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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,代码的其余部分将保持不变,就像这些函数一开始就在类中一样:
let msc = new MySplitClass();
msc.myFunction();
msc.myOtherFunction();
Run Code Online (Sandbox Code Playgroud)
同样,由于在实际调用函数之前什么也不会发生,因此只要BindToClass()先调用函数,就无需担心函数顺序。类文件内部和外部的每个函数仍然可以像往常一样访问类内的任何属性或函数。
小智 5
我选择将所有私有变量/函数放在一个名为 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));
}
}
Run Code Online (Sandbox Code Playgroud)
文件: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;
}
Run Code Online (Sandbox Code Playgroud)
文件:main.js
const { Person } = require('./person.js');
let me = new Person();
me.setAge(17);
console.log(`I'm ${me.getAge()} years old`);
Run Code Online (Sandbox Code Playgroud)
输出:
I'm 17 years old
Run Code Online (Sandbox Code Playgroud)
请注意,为了不在 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));
}
}
}
}
Run Code Online (Sandbox Code Playgroud)