2010-11-14 5 views
36

Могу ли я сделать что-то вроде ?:Как перегрузить конструктор объекта в 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; 
} 

ответ

34

Вы не можете этого сделать, поскольку JavaScript не является строго типизированным языком, он не увидит разницу между формой и именем пользователя. Вы можете создать несколько функций, таких как createUserFromForm(form) и createUserFromUserInfo(userName, password,...), или вы можете попробовать использовать сингулярный конструктор без указанных аргументов, а затем использовать аргументы, чтобы проверить ввод и решить, что делать.

6

Нет, вы не можете, JavaScript не поддерживает перегрузку любого рода.

Что вы можете сделать, это либо передать объект, который уже был заполнен значениями в свой конструктор, а затем захватить значения из объекта, но это дублирует код.

Или вы можете создать конструктор по умолчанию и добавить такие методы, как initFromUser или setFromForm, которые затем принимают соответствующие параметры и устанавливают значения объектов, new User().initFormForm(form) выглядит довольно чистым для меня.

20

Мне нравится Илья Володиных ответ, и я думал, что я хотел бы добавить это в качестве примера:

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

Есть, вероятно, более хорошие способы сделать это, но это только один пример.

5

Перегрузка конструктора или любая другая функция Javascript путем подсчета числа аргументов:

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

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

Вы также можете установить параметры по умолчанию, обнаруживая, сколько аргументов отсутствуют.

0

Вы можете легко имитировать перегруженные методы и конструкторы, используя комбинацию строк 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;