[英]What is the most elegant way to accept and handle different options in JavaScript constructor?
I'm trying to write a JavaScript class constructor that can accept multiple options (just like some command-line tools, eg OpenSSL).我正在尝试编写一个可以接受多个选项的 JavaScript 类构造函数(就像一些命令行工具,例如 OpenSSL)。 For example:
例如:
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
}
When the class is instantiated, this.public
is required, but this.private
is optional.当类被实例化时,
this.public
是必需的,而this.private
是可选的。 The conditional logic guarantees that if this.public
is not provided, an error will be thrown.条件逻辑保证如果
this.public
没有提供,就会抛出错误。
For the first parameter pathOrSize
, there are two possible input types so I use an if-else here to check the type.对于第一个参数
pathOrSize
,有两种可能的输入类型,所以我在这里使用 if-else 来检查类型。 Then if it's string
, based on the value of isPublic
, we will get two more different scenarios that need to be handled.那么如果是
string
,根据isPublic
的值,我们会得到另外两个不同的场景需要处理。 In my case, there are more options, which make the code snippet above looks even worse.就我而言,有更多选项,这使得上面的代码片段看起来更糟。 It works, but it's verbose and hard to read :(
它有效,但冗长且难以阅读:(
Given the fact that JavaScript doesn't support overloading (like Java) and pattern matching (like Rust), what's the most elegant or efficient way to handle situations like this ?鉴于 JavaScript 不支持重载(如 Java)和模式匹配(如 Rust),那么处理这种情况的最优雅或最有效的方法是什么?
Thanks for any solutions or thoughts!感谢您提供任何解决方案或想法!
A typical way to differentiate between parameters, is to provide an alternative, static function to create an instance.区分参数的典型方法是提供替代的静态函数来创建实例。 This is how it is done for some native classes.
这就是一些原生类的做法。 For instance,
Array
has Array.of
, Array.from
, and Object
has Object.fromEntries
, Object.create
, ...例如,
Array
有Array.of
、 Array.from
,而Object
有Object.fromEntries
、 Object.create
,...
If we follow that pattern, your example code could become:如果我们遵循该模式,您的示例代码可能变为:
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");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.