web-dev-qa-db-fra.com

Comment surcharger le constructeur d'un objet en JS (Javascript)?

Puis-je faire quelque chose comme?:

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;
}
41
orshachar

Vous ne pouvez pas faire cela, puisque JavaScript n'est pas un langage fortement typé, il ne verra pas de différence entre le formulaire et le nom d'utilisateur. Vous pouvez créer plusieurs fonctions comme createUserFromForm(form) et createUserFromUserInfo(userName, password,...) ou vous pouvez essayer d'utiliser un constructeur singulier sans argument spécifié, puis utiliser la collection arguments pour vérifier l'entrée et décider quoi faire.

40
Ilya Volodin

J'aime la réponse d'Ilya Volodins et j'ai pensé ajouter ceci comme exemple:

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});

Il existe probablement de meilleures façons de procéder, mais ce n'est qu'un exemple.

21
Patrik

Non, vous ne pouvez pas, JavaScript ne prend en charge aucune surcharge.

Ce que vous pouvez faire est de passer un objet qui a déjà été rempli avec les valeurs dans votre constructeur, puis de récupérer les valeurs de l'objet, mais cela duplique le code.

Ou vous pouvez créer un constructeur par défaut et ajouter des méthodes telles que initFromUser ou setFromForm qui prennent ensuite les paramètres respectifs et définissent les valeurs des objets, new User().initFormForm(form) me semble assez propre.

8
Ivo Wetzel

Vous pouvez facilement simuler des méthodes et des constructeurs surchargés à l'aide d'une combinaison de chaînes JSON et de la commande typeof. Voir l'exemple ci-dessous - vous l'attribut val se forme à partir du type de données entrant:

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;
0
Randhir Rawatlal