你能在 es6 及更高版本中创建多个构造函数吗?
Can you make multiple constructors in es6 and up?
问题
所以基本上我正在尝试使用多个构造函数制作一个 class 以便它更加用户友好。但是当我 运行 代码输出时:
SyntaxError: /FileSystem.js: Duplicate constructor in the same class (13:2)
我知道 可以回答这个问题,但我的代码对每个构造函数都有不同的参数:
Va运行 Sukheja 的代码
function Book() {
//just creates an empty book.
}
function Book(title, length, author) {
this.title = title;
this.Length = length;
this.author = author;
}
我的代码
class File
constructor(Name, Type, Data) {
this.Name = Name
this.Type = Type
this.Data = Data
}
constructor(FileName, Data) {
let FileNameSplit = FileName.split('.').pop();
this.Type = FileNameSplit[FileNameSplit.length - 1];
let NameSplit = FileNameSplit.pop()
this.Name = FileName;
this.Data = Data
}
}
如您所见,我的代码有 2 个构造函数(一个带有 constructor(Name, Type, Data) {
,另一个带有 constructor(FileName, Data) {
)。所以你可以看到使用 Saransh Kataria 的代码是行不通的。
.
Saransh Kataria 的代码
constructor(title, length, author) {
if(!arguments.length) {
// empty book
}
else {
this.title = title;
this.Length = length;
this.author = author;
}
}
额外信息
IDE: Codesandbox
浏览器: Chrome
完整代码:
class File {
/**
*
* @param {String} Name Name Of File
* @param {(String|Number)} Type File Type / Exstention
* @param {Array} Data
*/
constructor(Name, Type, Data) {
this.Name = Name
this.Type = Type
this.Data = Data
}
constructor(FileName, Data) {
let FileNameSplit = FileName.split('.').pop();
this.Type = FileNameSplit[FileNameSplit.length - 1];
let NameSplit = FileNameSplit.pop()
this.Name = FileName;
this.Data = Data
}
}
let Blob1 = new Blob([""])
console.log(Blob1)
Javascript 不支持定义多个构造函数。看起来你只是想做函数重载。
在Javascript中,你不会这样做。相反,您使用您期望的最大参数数量声明版本,并动态测试 OP 传递的内容,并根据传递或未传递的内容调整您的行为。
您可以在 Javascript 此处查看函数重载的一般说明:
How to overload functions in javascript?
如果构造函数的版本差异很大,那么您可以将其更改为仅采用一个对象,然后在调用函数之前将所需的属性分配给该对象。然后您的代码将询问对象并查看传递的内容并相应地调整其行为。
例如,要同时支持这两个:
class File {
constructor(Name, Type, Data) {
this.Name = Name
this.Type = Type
this.Data = Data
}
constructor(FileName, Data) {
let FileNameSplit = FileName.split('.').pop();
this.Type = FileNameSplit[FileNameSplit.length - 1];
let NameSplit = FileNameSplit.pop()
this.Name = FileName;
this.Data = Data
}
}
您可以通过多种方式执行此类操作。最简单的是,如果所需参数的类型不同,而我们不确切知道这些参数是什么类型。在不知道这些类型的情况下,我可能只是传入一个具有命名属性的对象:
class File
constructor(options) {
if (options.Name && options.Type) {
this.Name = options.Name
this.Type = options.Type
this.Data = options.Data
} else if (options.FileName && options.Data) {
let FileNameSplit = options.FileName.split('.').pop();
this.Type = FileNameSplit[FileNameSplit.length - 1];
let NameSplit = FileNameSplit.pop()
this.Name = options.FileName;
this.Data = options.Data
} else {
throw new Error("improper arguments to File constructor);
}
}
}
仅供参考,Javascript 中的习惯是 属性 名称和参数名称以及常规变量名称以小写字母开头(我在代码中保留了您已有的名称)。 Class 名称通常大写。
因为您知道 Data
参数是唯一的数组参数,您可以像这样动态检测传递了哪些参数:
class File {
// args can be in either of these forms:
// (Name, Type, Data)
// (FileName, Data)
constructor(Name, Type, Data) {
if (Array.isArray(Data)) {
// args must be (Name, Type, Data)
this.Name = Name
this.Type = Type
this.Data = Data
} else if (Array.isArray(Type)) {
// args must be (FileName, Data)
const FileName = Name;
this.Name = FileName;
this.Data = Type;
let FileNameSplit = FileName.split('.').pop();
this.Type = FileNameSplit[FileNameSplit.length - 1];
} else {
throw new TypeError("unexpected or missing arguments to File constructor")
}
}
}
问题
所以基本上我正在尝试使用多个构造函数制作一个 class 以便它更加用户友好。但是当我 运行 代码输出时:
SyntaxError: /FileSystem.js: Duplicate constructor in the same class (13:2)
我知道
Va运行 Sukheja 的代码
function Book() {
//just creates an empty book.
}
function Book(title, length, author) {
this.title = title;
this.Length = length;
this.author = author;
}
我的代码
class File
constructor(Name, Type, Data) {
this.Name = Name
this.Type = Type
this.Data = Data
}
constructor(FileName, Data) {
let FileNameSplit = FileName.split('.').pop();
this.Type = FileNameSplit[FileNameSplit.length - 1];
let NameSplit = FileNameSplit.pop()
this.Name = FileName;
this.Data = Data
}
}
如您所见,我的代码有 2 个构造函数(一个带有 constructor(Name, Type, Data) {
,另一个带有 constructor(FileName, Data) {
)。所以你可以看到使用 Saransh Kataria 的代码是行不通的。
.
Saransh Kataria 的代码
constructor(title, length, author) {
if(!arguments.length) {
// empty book
}
else {
this.title = title;
this.Length = length;
this.author = author;
}
}
额外信息
IDE: Codesandbox
浏览器: Chrome
完整代码:
class File {
/**
*
* @param {String} Name Name Of File
* @param {(String|Number)} Type File Type / Exstention
* @param {Array} Data
*/
constructor(Name, Type, Data) {
this.Name = Name
this.Type = Type
this.Data = Data
}
constructor(FileName, Data) {
let FileNameSplit = FileName.split('.').pop();
this.Type = FileNameSplit[FileNameSplit.length - 1];
let NameSplit = FileNameSplit.pop()
this.Name = FileName;
this.Data = Data
}
}
let Blob1 = new Blob([""])
console.log(Blob1)
Javascript 不支持定义多个构造函数。看起来你只是想做函数重载。
在Javascript中,你不会这样做。相反,您使用您期望的最大参数数量声明版本,并动态测试 OP 传递的内容,并根据传递或未传递的内容调整您的行为。
您可以在 Javascript 此处查看函数重载的一般说明:
How to overload functions in javascript?
如果构造函数的版本差异很大,那么您可以将其更改为仅采用一个对象,然后在调用函数之前将所需的属性分配给该对象。然后您的代码将询问对象并查看传递的内容并相应地调整其行为。
例如,要同时支持这两个:
class File {
constructor(Name, Type, Data) {
this.Name = Name
this.Type = Type
this.Data = Data
}
constructor(FileName, Data) {
let FileNameSplit = FileName.split('.').pop();
this.Type = FileNameSplit[FileNameSplit.length - 1];
let NameSplit = FileNameSplit.pop()
this.Name = FileName;
this.Data = Data
}
}
您可以通过多种方式执行此类操作。最简单的是,如果所需参数的类型不同,而我们不确切知道这些参数是什么类型。在不知道这些类型的情况下,我可能只是传入一个具有命名属性的对象:
class File
constructor(options) {
if (options.Name && options.Type) {
this.Name = options.Name
this.Type = options.Type
this.Data = options.Data
} else if (options.FileName && options.Data) {
let FileNameSplit = options.FileName.split('.').pop();
this.Type = FileNameSplit[FileNameSplit.length - 1];
let NameSplit = FileNameSplit.pop()
this.Name = options.FileName;
this.Data = options.Data
} else {
throw new Error("improper arguments to File constructor);
}
}
}
仅供参考,Javascript 中的习惯是 属性 名称和参数名称以及常规变量名称以小写字母开头(我在代码中保留了您已有的名称)。 Class 名称通常大写。
因为您知道 Data
参数是唯一的数组参数,您可以像这样动态检测传递了哪些参数:
class File {
// args can be in either of these forms:
// (Name, Type, Data)
// (FileName, Data)
constructor(Name, Type, Data) {
if (Array.isArray(Data)) {
// args must be (Name, Type, Data)
this.Name = Name
this.Type = Type
this.Data = Data
} else if (Array.isArray(Type)) {
// args must be (FileName, Data)
const FileName = Name;
this.Name = FileName;
this.Data = Type;
let FileNameSplit = FileName.split('.').pop();
this.Type = FileNameSplit[FileNameSplit.length - 1];
} else {
throw new TypeError("unexpected or missing arguments to File constructor")
}
}
}