我们可以在 javascript 中将通用对象转换为自定义对象类型吗?

问题描述 投票:0回答:7

比如我在代码某处已经有了这个对象,它是一个泛型对象:

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

我有一个 Person 对象的构造函数:

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

是否有一个简单的语法允许我们将 person1 转换为 Person 类型的对象?

javascript oop object
7个回答
66
投票

@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


8
投票

但是如果你想把你的

person1
对象当作一个
Person
,你可以在
Person
上调用
person1
原型的方法,使用
call

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

尽管这显然不适用于在 Person 构造函数内部创建的特权方法,例如您的

getFullName
方法。


7
投票

这不完全是一个答案,而是分享我的发现,并希望得到一些支持/反对它的批判性论据,具体来说我不知道它有多有效。

我最近需要为我的项目做这个。我使用

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

2
投票

这借用了这里的其他一些答案,但我认为它可能对某人有所帮助。如果你在你的自定义对象上定义了以下函数,那么你就有了一个工厂函数,你可以将一个通用对象传递给它,它会为你返回一个类的实例。

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

2
投票

这只是 Sayan Pal 答案的总结,形式较短,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",
    ...

2
投票

这对我有用。对于简单的对象来说很简单。

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 相同“格式”的通用对象。 我希望这也能帮助别人。


0
投票

如果你喜欢,这里有一个方法。 1st 制作一个具有您所有想要的属性的对象。 然后使用您的自定义值调用此对象。 这是JSFiddle的链接,也是

的主要部分

 function Message(obj) {
  this.key = Date.now();
  this.text = "";
  this.type = "client";
  this.status = 0;
  this.senderID = "";
  this.name = "";
  this.photoURL = "";
  this.metaData = [];
  this.time = new Date().toISOString();
  
  for (var prop in obj) {
    if (this.hasOwnProperty(prop)) {
      this[prop] = obj[prop];
    }else{
        this.metaData = [ ...this.metaData, {[prop]: obj[prop]} ];
    }
  }
}

 const getAllMessages = function (messages=[]) {
  var newMessages = [];
  for (var i = 0; i < messages.length; i++) {
    newMessages.push(new Message(messages[i]));
  }
  return newMessages;
};

var messages = [{
  name: "Jhon",
  text: "Hello 1"
}, {
  name: "Smith",
  text: "Hello 2",
  meta1: "meta data 1"
}];

console.log("Single Instances", new Message(messages[0]));

console.log("Multiple Instances",getAllMessages(messages));

© www.soinside.com 2019 - 2024. All rights reserved.