wake-up-neo.net

Kann ein generisches Objekt in JavaScript in einen benutzerdefinierten Objekttyp umgewandelt werden?

Zum Beispiel habe ich dieses Objekt bereits im Code, es ist ein generisches Objekt:

var person1={lastName:"Freeman",firstName:"Gordon"};

Ich habe den Konstruktor für ein Personenobjekt:

function Person(){
 this.getFullName=function(){
  return this.lastName + ' ' + this.firstName;
 }
}

Gibt es eine einfache Syntax, mit der wir person1 in ein Objekt vom Typ Person konvertieren können?

42
bobo

Die Antwort von @PeterOlson wird möglicherweise am Tag zurückgearbeitet, aber es sieht so aus, als Object.create geändert wurde . Ich würde für den Copy-Konstruktor-Weg gehen, wie @ user166390 in den Kommentaren sagte.
Der Grund, warum ich diesen Beitrag nekromanisiert habe, ist, dass ich eine solche Implementierung brauchte.

Heutzutage können wir Object.assign (Credits zu @SayanPal-Lösung) & ES6-Syntax verwenden:

class Person {
  constructor(obj) {
    obj && Object.assign(this, obj);
  }

  getFullName() {
    return `${this.lastName} ${this.firstName}`;
  }
}

Verwendungszweck:

const newPerson = new Person(person1)
newPerson.getFullName() // -> Freeman Gordon

ES5 Antwort unten

function Person(obj) {
    for(var prop in obj){
        // for safety you can use the hasOwnProperty function
        this[prop] = obj[prop];
    }
}

Verwendungszweck:

var newPerson = new Person(person1);
console.log(newPerson.getFullName()); // -> Freeman Gordon

Bei Verwendung einer kürzeren Version, 1,5 Liner:

function Person(){
    if(arguments[0]) for(var prop in arguments[0]) this[prop] = arguments[0][prop];
}

jsfiddle

33
A1rPun

Nein.  

Wenn Sie jedoch Ihr person1-Objekt wie eine Person behandeln möchten, können Sie Methoden mit Persons Prototyp auf person1 mit call aufrufen:

Person.prototype.getFullNamePublic = function(){
    return this.lastName + ' ' + this.firstName;
}
Person.prototype.getFullNamePublic.call(person1);

Dies funktioniert jedoch offensichtlich nicht für privilegierte Methoden, die im Person-Konstruktor erstellt wurden - wie Ihre getFullName-Methode. 

6
Adam Rackis

Dies ist keine exakte Antwort, sondern teilt meine Ergebnisse und hoffentlich kritische Argumente dafür/dagegen, da ich mir nicht bewusst ist, wie effizient es ist.

Ich musste dies kürzlich für mein Projekt tun. Ich habe dies mit Object.assign gemacht, genauer gesagt, es ist ungefähr so: Object.assign(new Person(...), anObjectLikePerson).

Hier ist ein Link zu meinem JSFiddle und auch der Hauptteil des Codes:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;

  this.getFullName = function() {
    return this.lastName + ' ' + this.firstName;
  }
}

var persons = [{
  lastName: "Freeman",
  firstName: "Gordon"
}, {
  lastName: "Smith",
  firstName: "John"
}];

var stronglyTypedPersons = [];
for (var i = 0; i < persons.length; i++) {
  stronglyTypedPersons.Push(Object.assign(new Person("", ""), persons[i]));
}
3
Sayan Pal

Dies geht aus einigen anderen Antworten hervor, aber ich dachte, es könnte jemandem helfen. Wenn Sie die folgende Funktion für Ihr benutzerdefiniertes Objekt definieren, haben Sie eine Factory-Funktion, an die Sie ein generisches Objekt übergeben können, und es wird Ihnen eine Instanz der Klasse zurückgeben.

CustomObject.create = function (obj) {
    var field = new CustomObject();
    for (var prop in obj) {
        if (field.hasOwnProperty(prop)) {
            field[prop] = obj[prop];
        }
    }

    return field;
}

Verwenden Sie so

var typedObj = CustomObject.create(genericObj);
1
Obi Onuorah

Dies ist nur eine Zusammenfassung der Antwort von Sayan Pal in einer kürzeren Form im ES5-Stil:

var Foo = function(){
    this.bar = undefined;
    this.buzz = undefined;
}

var foo = Object.assign(new Foo(),{
    bar: "whatever",
    buzz: "something else"
});

Ich mag es, weil es am nächsten an der sehr sauberen Objektinitialisierung in .Net liegt.

var foo = new Foo()
{
    bar: "whatever",
    ...
1
pasx

Das hat bei mir funktioniert. Bei einfachen Objekten ist das einfach.

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  getFullName() {
    return this.lastName + " " + this.firstName;
  }

  static class(obj) {
    return new Person(obj.firstName, obj.lastName);
  }
}

var person1 = {
  lastName: "Freeman",
  firstName: "Gordon"
};

var gordon = Person.class(person1);
console.log(gordon.getFullName());

Ich war auch auf der Suche nach einer einfachen Lösung, und auf dieser Grundlage habe ich alle anderen Antworten und meine Recherchen gefunden. Grundsätzlich hat die Klasse Person einen anderen Konstruktor, genannt 'Klasse', der mit einem generischen Objekt desselben 'Formats' wie Person ..__ arbeitet. Ich hoffe, das könnte auch jemandem helfen.

0
Orwol Chiles