How to overload constructor of an Object in JS (Javascript)?

JavascriptConstructorOverriding

Javascript Problem Overview


Can I do something like?:

function User(form) {
	this._username = form.username.value;
	this._password = form.password.value;
	this._surname = form.surname.value;
	this._lastname = form.lastname.value;
	this._birthdate = form.b_day.value+"-"+form.b_month.value+"-"+form.b_year.value;
	this._avatar = form.avatar;
	this._messages = new Array();
	this._messagesCount=0;
}

function User(userName,password,surname,lastName,birthdate) {
	this._username = userName;
	this._password = password;
	this._surname = surname;
	this._lastname = lastName;
	this._birthdate = birthdate;
	this._avatar = form.avatar;
	this._messages = new Array();
	this._messagesCount=0;
}

Javascript Solutions


Solution 1 - Javascript

You can't do that, since JavaScript is not a strongly typed language it will not see a difference between form and userName. You can create multiple function like createUserFromForm(form) and createUserFromUserInfo(userName, password,...) or you could try to use a singular constructor with no arguments specified and then use arguments collection to check the input and decide what to do.

Solution 2 - Javascript

I like Ilya Volodins answer and I thought I would add this as an example:

function foo() {
	var evt = window.event || arguments[1] || arguments.callee.caller.arguments[0];
	var target = evt.target || evt.srcElement;
	
	var options = {};
	
	if (arguments[0]) options = arguments[0];
	
	var default_args = {
		'myNumber'		:	42,
		'myString'		:	'Hello',
		'myBoolean'		:	true
	}
	for (var index in default_args) {
		if (typeof options[index] == "undefined") options[index] = default_args[index];
	}
	
	//Do your thing
	
}

//then you call it like this
foo();

//or

foo({'myString' : 'World'});

//or

foo({'myNumber' : 666, 'myString' : 'World', 'myBoolean' : false});

There are probably nicer ways of doing this but this just one example.

Solution 3 - Javascript

No you can't, JavaScript does not support overloading of any kind.

What you can do is either pass an object which has already been populated with the values into your constructor and then grab the values from the object, but this which duplicates code.

Or you can create a default constructor and add methods such as initFromUser or setFromForm which then take the respective parameters and setup the objects values, new User().initFormForm(form) looks pretty clean to me.

Solution 4 - Javascript

Overload the constructor or any other Javascript function by counting the number of arguments:

function FooString()
{	if(arguments.length>0)
	{	this.str=arguments[0];
		return;
	}
	this.str="";
}

var s1=new FooString;
var s2=new FooString("hello world");

You can also set default arguments by detecting how many arguments are missing.

Solution 5 - Javascript

You can create constructor using ES6 features as below.

class Person {
  constructor(name, surname) {
    if (typeof name === "object") {
      this.name = name.name;
      this.surname = name.surname;
    } else {
      this.name = name;
      this.surname = surname;
    }
  }
}

const person1 = new Person("Rufat", "Gulabli");
const person2 = new Person({ name: "Rufat", surname: "Gulabli" });
const person3 = new Person();
console.log(person1);
console.log(person2);
console.log(person3);

Print Out:

  • Person { name: 'Rufat', surname: 'Gulabli' }
  • Person { name: 'Rufat', surname: 'Gulabli' }
  • Person { name: undefined, surname: undefined }

Solution 6 - Javascript

You can easily simulate overloaded methods and constructors using a combination of JSON strings and the typeof command. See example below - you the val attribute gets shaped from the type of data coming in:

function test(vals)
    {
        this.initialise = function (vals) {

            if (typeof (vals) == 'undefined')
            {
                this.value = 10;
            }
            else if (Object.prototype.toString.call(vals) === '[object Array]')
            {
                this.value = vals[0];
            }
            else if (typeof (vals) === 'object') {
                if (vals.hasOwnProperty('x')) {
                    this.value = vals.x;
                }
                else if (vals.hasOwnProperty('y')) {
                    this.value = vals.y;
                }
            }
            else {
                this.value = vals; // e.g. it might be a string or number
            }
            
        }

        this.otherMethods = function () {
            // other methods in the class
        }

        this.initialise(vals);
    }

    var obj1 = test(); // obj1.val = 10;
    var obj2 = test([30, 40, 50]); // obj1.val = 30;
    var obj3 = test({ x: 60, y: 70 }); // obj1.val = 60;
    var obj4 = test({ y: 80 }); // obj1.val = 80;
    var obj5 = test('value'); // obj1.val = 'value';
    var obj6 = test(90); // obj1.val = 90;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionorshacharView Question on Stackoverflow
Solution 1 - JavascriptIlya VolodinView Answer on Stackoverflow
Solution 2 - JavascriptPatrikView Answer on Stackoverflow
Solution 3 - JavascriptIvo WetzelView Answer on Stackoverflow
Solution 4 - JavascriptRobin RoweView Answer on Stackoverflow
Solution 5 - JavascriptRufat GulabliView Answer on Stackoverflow
Solution 6 - JavascriptRandhir RawatlalView Answer on Stackoverflow