Reputation: 66
So basically I'm trying to make a class with multi constructors so that it is more user friendly. but when I run the code it outputs this:
SyntaxError: /FileSystem.js: Duplicate constructor in the same class (13:2)
I know that Creating multiple constructor in ES6 kind of answers this question but my code has different parameters for each constructor:
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
}
}
As you can see, my code has 2 constructors (one with constructor(Name, Type, Data) {
and the other with constructor(FileName, Data) {
). so you can see using Saransh Kataria's Code, won't work.
.
constructor(title, length, author) {
if(!arguments.length) {
// empty book
}
else {
this.title = title;
this.Length = length;
this.author = author;
}
}
IDE: Codesandbox
Browser: Chrome
Full Code:
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)
Upvotes: 0
Views: 3079
Reputation: 707198
Javascript does not support defining multiple constructors. It appears you're just trying to do function overloading.
In Javascript, you don't do it this way. Instead, you declare the version with the maximum number of parameters you expect and you dynamically test for what the OP passed and adjust your behavior based on what was or wasn't passed.
You can see a general description of function overloading in Javascript here:
How to overload functions in javascript?
If you have widely varying versions of the constructor, then you can change it to take exactly one object and then just assign the desired properties to the object before calling the function. Your code will then interrogate the object and see what was passed and adjust its behavior accordingly.
For example, to support both of these:
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
}
}
there are several ways you could do something like this. The easiest is if the types of the desired parameters are distinct and we don't know exactly what types these are. Without knowing those types, I'd probably just pass in an object with named properties:
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);
}
}
}
FYI, it's customary in Javascript that property names and argument names and regular variable names start with a lowercase letter (I left the code with the names you already had). Class names are typically capitalized.
Since you know that the Data
argument is the only argument that is an array, you can dynamically detect which arguments are passed like this:
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")
}
}
}
Upvotes: 2