如何在JS(Javascript)中重载对象的构造函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4179283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 11:16:34  来源:igfitidea点击:

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

javascriptconstructoroverriding

提问by orshachar

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

回答by Ilya Volodin

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 argumentscollection to check the input and decide what to do.

你不能这样做,因为 JavaScript 不是一种强类型语言,它不会看到表单和用户名之间的区别。您可以创建多个函数,例如createUserFromForm(form)andcreateUserFromUserInfo(userName, password,...)或者您可以尝试使用不指定参数的单一构造函数,然后使用参数集合来检查输入并决定要做什么。

回答by Patrik

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

我喜欢 Ilya Volodins 的回答,我想我会添加这个作为例子:

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.

可能有更好的方法来做到这一点,但这只是一个例子。

回答by Ivo Wetzel

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

不,你不能,JavaScript 不支持任何类型的重载。

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 initFromUseror setFromFormwhich then take the respective parameters and setup the objects values, new User().initFormForm(form)looks pretty clean to me.

或者,您可以创建一个默认构造函数并添加诸如initFromUser或 之类的方法setFromForm,然后使用相应的参数并设置对象值,new User().initFormForm(form)对我来说看起来很干净。

回答by Robin Rowe

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

通过计算参数的数量重载构造函数或任何其他 Javascript 函数:

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.

您还可以通过检测缺少多少参数来设置默认参数。

回答by Rufat Gulabli

You can create constructor using ES6 features as below.

您可以使用 ES6 特性创建构造函数,如下所示。

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 }
  • 人{姓名:'Rufat',姓氏:'Gulabli'}
  • 人{姓名:'Rufat',姓氏:'Gulabli'}
  • 人{名称:未定义,姓氏:未定义}

回答by Randhir Rawatlal

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:

您可以使用 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;