web-dev-qa-db-ja.com

JS(Javascript)でオブジェクトのコンストラクターをオーバーロードする方法は?

次のようなことができますか?:

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

JavaScriptは厳密に型指定された言語ではないため、フォームとuserNameの違いはわかりません。 createUserFromForm(form)createUserFromUserInfo(userName, password,...)のような複数の関数を作成するか、引数を指定せずに単一のコンストラクターを使用してからargumentsコレクションを使用して入力をチェックすることができます。そして何をすべきかを決定します。

40
Ilya Volodin

私はイリヤ・ヴォロディンの回答が好きで、これを例として追加すると思いました:

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

これを行うにはおそらくもっと良い方法がありますが、これは一例です。

21
Patrik

いいえ、できません。JavaScriptはいかなる種類のオーバーロードもサポートしていません。

できることは、値が既に設定されているオブジェクトをコンストラクタに渡し、オブジェクトから値を取得することですが、これはコードを複製します。

または、デフォルトのコンストラクタを作成し、initFromUsersetFromFormなどのメソッドを追加して、それぞれのパラメーターを取得してオブジェクト値を設定することもできます。new User().initFormForm(form)はかなりきれいに見えます。

8
Ivo Wetzel

引数の数をカウントして、コンストラクターまたはその他のJavaScript関数をオーバーロードします。

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

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

欠落している引数の数を検出することにより、デフォルトの引数を設定することもできます。

5
Robin Rowe

JSON文字列とtypeofコマンドの組み合わせを使用して、オーバーロードされたメソッドとコンストラクターを簡単にシミュレートできます。以下の例を参照してください-val属性は、入ってくるデータのタイプから整形されます:

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