你能在es6及以上版本中生成多个构造函数吗



问题

因此,基本上,我试图创建一个具有多构造函数的类,这样它对用户更友好。但当我运行代码时,它输出的是:

SyntaxError: /FileSystem.js: Duplicate constructor in the same class (13:2)

我知道在ES6中创建多个构造函数可以回答这个问题,但我的代码对每个构造函数都有不同的参数:

Varun 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
}
}

正如您所看到的,我的代码有两个构造函数(一个带有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中函数重载的一般描述:

如何在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中,属性名、参数名和常规变量名通常以小写字母开头(我在代码中留下了您已经有的名称(。类名通常是大写的。


由于您知道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")
}
}
}

相关内容

最新更新