在JavaScript构造函数中接受和处理不同选项的最优雅的方式是什么?



我试图写一个JavaScript类构造器,可以接受多个选项(就像一些命令行工具,例如OpenSSL)。例如:

class myClass {
constructor(pathOrSize, isPublic) {
// Receive an file path
if (typeof pathOrSize === 'string') {
if (isPublic) {
// Read public key file
this.public = ...
} else {
// Read private key file, and then generate public key instance
this.private = ...
this.public = ...
}
} else if (typeof pathOrSize === 'number') {
// Create a new key pair based on the given size
this.private = ...
this.public = ...
} else {
// Throw an error
}
}
// Use this.public (or this.private, if provided) to encrypt/decrypt message
}

实例化类时,this.public是必需的,但this.private是可选的。条件逻辑保证如果没有提供this.public,将抛出一个错误。

对于第一个参数pathOrSize,有两种可能的输入类型,因此我在这里使用if-else来检查类型。然后如果是string,基于isPublic的值,我们将得到另外两个需要处理的不同场景。在我的例子中,有更多的选择,使上面的代码片段中看起来更糟。它可以工作,但它冗长且难以阅读:(

考虑到JavaScript不支持重载(如Java)和模式匹配(如Rust),处理这种情况的最优雅或最有效的方法是什么

?感谢您的任何解决方案或想法!

区分参数的一种典型方法是提供另一种静态函数来创建实例。这就是对一些本地类的处理方式。例如,ArrayArray.of,Array.from,ObjectObject.fromEntries,Object.create,…

如果我们遵循这个模式,你的示例代码可能变成:

class MyClass {
static fromFile(path, isPublic=true) {
// read key file
const content = ...
// Pass the appropriate arguments to constructor
return isPublic ? new this(null, content) : new this(content);
}
static fromSize(size) {
// Create new key pairs based on the given size
const privateKey = ...
const publicKey = ...
return new this(privateKey, publicKey);
}
// Constructor is dumb: it has little logic
constructor(privateKey, publicKey) {
// If no public key is given, produce it from the private key
if (publicKey === undefined) {
if (privateKey === undefined) throw Error("must provide at least one key");
// Generate public key instance from private key
publicKey = ...
}
this.privateKey = privateKey ?? null; // turn undefined into null
this.publicKey = publicKey;
}
}
// Example calls:
let x = MyClass.fromFile("/testPublic.key");
let y = MyClass.fromSize(5);
let z = new MyClass("a", "b");

最新更新