Можем ли мы привести общий объект к пользовательскому типу объекта в JavaScript? - PullRequest
48 голосов
/ 05 января 2012

Например, у меня уже есть этот объект где-то в коде, это общий объект:

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

У меня есть конструктор для объекта Person:

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

Существует ли простой синтаксис, который позволяет нам преобразовывать person1 в объект типа Person?

Ответы [ 6 ]

39 голосов
/ 22 мая 2014

Ответ @PeterOlson может быть обработан в тот же день, но похоже, что Object.create изменился.Я хотел бы пойти по пути конструктора копирования, как @ user166390 сказал в комментариях.
Причина, по которой я некромантировал этот пост, в том, что мне нужна такая реализация.

В настоящее время мы можем использовать Object.assign ( кредитов к решению @SayanPal ) и синтаксис ES6:

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

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

Использование:

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

ES5 ответ ниже

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

Использование:

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

Использование более короткой версии, вкладыш 1,5:

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

jsfiddle

7 голосов
/ 05 января 2012

Нет.

Но если вы хотите обработать ваш person1 объект, как если бы он был Person, вы можете вызывать методы прототипа Person на person1 с call:

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

Хотя это, очевидно, не сработает для привилегированных методов, созданных внутри конструктора Person - например, для вашего getFullName метода.

3 голосов
/ 13 января 2016

Это не совсем ответ, скорее, я делюсь своими выводами и, надеюсь, получаю какой-то критический аргумент за / против, так как конкретно я не знаю, насколько это эффективно.

Недавно у меня возникла необходимость сделать это для моего проекта. Я сделал это, используя Object.assign, точнее это делается примерно так: Object.assign(new Person(...), anObjectLikePerson).

Вот ссылка на мой JSFiddle , а также основная часть кода:

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]));
}
1 голос
/ 15 мая 2018

Это всего лишь завершение ответа Саян Пал в более короткой форме, стиль ES5:

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

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

Мне это нравится, потому что он наиболее близок к очень аккуратной инициализации объекта в .Net:

var foo = new Foo()
{
    bar: "whatever",
    ...
1 голос
/ 16 декабря 2016

Это заимствовано из нескольких других ответов здесь, но я подумал, что это может кому-то помочь. Если вы определяете следующую функцию для своего пользовательского объекта, то у вас есть фабричная функция, в которую вы можете передать универсальный объект, и он вернет вам экземпляр класса.

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

    return field;
}

Используйте вот так

var typedObj = CustomObject.create(genericObj);
0 голосов
/ 01 ноября 2018

Это сработало для меня. Это просто для простых объектов.

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

Я также искал простое решение, и это то, что я придумал, основываясь на всех других ответах и ​​моих исследованиях. По сути, у класса Person есть другой конструктор, называемый «класс», который работает с универсальным объектом того же «формата», что и Person . Надеюсь, это кому-нибудь тоже поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...