2016-05-30 3 views
1

Ich versuche ein neues Objekt zu erstellen, indem ich ein bereits erstelltes Objekt verwende. Das ist, was ich zu erreichen versuchen:JavaScript-Konstruktor - Verwenden Sie ein Objekt?

var obj = {"Name" : "Patrick", "Age": 25, "Country": "US"}; 
document.writeln(JSON.stringify(obj) + "<br />"); 

function Person(name, age, country) { 
    this.name = name; 
    this.age = age; 
    this.country = country; 
} 

document.writeln(JSON.stringify(new Person(obj))); 

https://jsfiddle.net/dotjz9tb/

Wie Sie sehen können, Ich versuche, eine neue Person zu erstellen namens Patrick im Alter von 25, die in den USA leben geschieht. Mein Person Konstruktor verwendet einen Namen, ein Alter und ein Land als Parameter. Allerdings wurde mein Objekt bereits aus einer vorherigen Funktion erstellt, also würde ich gerne new Person(obj) machen und es würde ein neues Objekt basierend auf den Parametern obj erstellen.

Ich weiß, ich kann new Person(obj.name, obj.age, obj.country) tun, aber ich würde lieber den Konstruktor ein Objekt statt, während immer noch new Person("Jack", 52, "UK") tun können.

Ist so etwas möglich? Im Moment ist dies, wie es wirklich erstellt werden:

new Person(obj, undefined, undefined); 
//or 
{ 
    "name": { 
     "Name":" Patrick"," 
     Age":25, 
     "Country":"US" 
    } 
} 

Was bedeutet, dass age und country wird nichts eingestellt, während name auf mein Objekt festgelegt ist.

+0

rufen Wenn Konstruktor 'Funktion Person (obj) { this.name = obj.Name; this.age = obj.Age; this.country = obj.Land; } ' – Rayon

+0

@Rayon Dann müsste ich einen neuen Konstruktor erstellen, der auch ein Objekt nimmt, oder? – MortenMoulder

+0

Oder Bedingungen drin ... Etwas wie 'arguments.length'? – Rayon

Antwort

1

Sie haben viele Möglichkeiten.

Zum Beispiel könnten Sie Ihre Person polymorph auf Argumente machen, die es dauert.

function Person(name, age, country) { 
    if(arguments.length === 1 && typeof name === 'object') { 
     var data = arguments[0]; 
     name = data.name; //etc 
    } 
    //the rest of ctor code goes here 
} 

Oder BETTER Gebrauch Fabrik Funktion und halten Sie Ihre Konstruktorcode so einfach möglich

function copyPerson(obj) { 
    return new Person(obj.name, obj.age, obj.country); 
} 

//or even 
Person.copy = function(obj) { 
    return new this(obj.name, obj.age, obj.country) 
} 
+0

Erstellen einer neuen Funktion ist eine Art "meh". Ich würde lieber bei einem Konstrukteur bleiben. – MortenMoulder

+0

Nun, es liegt an dir. Aber Ihren Konstruktorcode zu komplex zu machen, ist ein Antipattern. Factory-Funktionen sind viel wartungsfreundlicher. –

+0

stimme ich völlig zu, aber ich möchte nur 'new Person()' und parse es entweder ein Objekt oder einige Parameter. – MortenMoulder

0

Dies ist, was Sie tun können, sowohl die Input-Formate zu unterstützen:

function Person(name, age, country) { 
     var obj; 
     if(typeof(name) === 'object'){ 
      obj = name; 
      name = obj.name; 
      age = obj.age; 
      country = obj.country; 
     } 
     this.name = name; 
     this.age = age; 
     this.country = country; 
    } 
+0

Bis jetzt sieht das wie die beste Option für mich aus. Vielen Dank. – MortenMoulder

+0

Eigentlich ist es nicht. Es ist am besten, diese Art von Polymorphie zu vermeiden. Verwenden Sie stattdessen eine "copy" -Methode für die Klasse, wie eine Antwort vorgeschlagen hat, oder eine "clone" -Methode für die Instanzen (im Prototyp). –

+0

Ja, dem stimme ich vollkommen zu, aber ich möchte es nicht "komplexer" machen, als es sein muss. – MortenMoulder

0
var Person = function(nameOrObj, age, country) { 
    if (typeof nameOrObj === 'object') { 
    this.name = nameOrObj.name 
    this.age = nameOrObj.age 
    this.country = nameOrObj.country 
    } else { 
    this.name = nameOrObj 
    this.age = age 
    this.country = country 
    } 
} 
+0

was ist los damit? – lipp

+0

Es scheint, jemand hat alle Antworten hier downvoted :) –

1

Im Allgemeinen ist es besser, polymorphe Schnittstellen zu vermeiden. Sie sind schwer zu pflegen, zu dokumentieren und zu erinnern.

In diesem Fall würde ich die Unterschrift des Konstruktor ändern, ein Objekt zu nehmen, so

function Person(data) { 
    Object.assign(this, data); 
} 

Jetzt können Sie es als

var patrick = new Person({name: 'Patrick', age: 25, country: 'US'}); 
var patrick2 = new Person(patrick); 
+0

Ja, das wäre der beste Weg, es zu tun. Absolut. Vielen Dank. – MortenMoulder

Verwandte Themen