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

Posted

技术标签:

【中文标题】我们可以在 javascript 中将通用对象转换为自定义对象类型吗?【英文标题】:Can we cast a generic object to a custom object type in javascript? 【发布时间】:2012-02-02 22:42:06 【问题描述】:

例如,我在代码的某处已经有了这个对象,它是一个通用对象:

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

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

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

是否有一种简单的语法可以让我们将 person1 转换为 Person 类型的对象?

【问题讨论】:

javascript 中没有强制转换,所以...简短的回答是否定的。更长的答案是......仍然没有。这是因为 [[prototype]] 只能在创建对象时设置。但是,人们可以对从 Person 到 person1 的方法/属性进行猴子修补(复制),无论如何,这是一些“类框架”使用的一种方法。我可能会在“复制构造函数”中从 person1 创建一个 new Person。 【参考方案1】:

@PeterOlson 的答案可能会在当天恢复,但看起来Object.create 已更改。 我会像 @user166390 在 cmets 中所说的那样采用复制构造方法。 我死灵这篇文章的原因是因为我需要这样的实现。

现在我们可以使用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

【讨论】:

“1.5 liner”版本的道具,喜欢。 但是这个答案实际上只是编写了大多数框架在其中的extend 函数......而Object.assign 是该函数的替代品......截至今天。只有 Internet Explorer 和 Safari Object.assign polyfill 并在真正的 Object.assign 不存在时使用它。在我的项目中,我有一段代码可以检查所需的功能,如果缺少任何功能,则为这些功能加载带有 polyfill 的第二个脚本。 @StijndeWitt 我必须同意在此解决方案上使用Object.assign。请参阅使用 assign 方法的@SayanPal 解决方案。我会在某个时候更新这个答案;) @StijndeWitt 是时候更新我的答案了!我看到了Object.assign的力量【参考方案2】:

没有。

但是,如果您希望将 person1 对象视为 Person,您可以使用 callperson1 上调用 Person 原型上的方法:

Person.prototype.getFullNamePublic = function()
    return this.lastName + ' ' + this.firstName;

Person.prototype.getFullNamePublic.call(person1);

虽然这显然不适用于在 Person 构造函数中创建的特权方法,例如您的 getFullName 方法。

【讨论】:

【参考方案3】:

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

我最近需要为我的项目执行此操作。我使用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]));

【讨论】:

这种语法非常好用且高效。大概也是要走的路吧。 Too bad some browsers don't support it yet. @A1rPun pollyfill 可用于这些情况:kangax.github.io/compat-table/es6/… 这是最好的答案。 assign() 和 create() 的区别在于 1) assign 使用非对象属性; 2) 分配忽略未知属性。【参考方案4】:

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

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

【讨论】:

我使用了一个从标准类扩展而来的自定义类。现在,当全局侦听器的回调完成时,它会返回一个标准的分类对象作为参数。我所做的是我尝试了所有符合我需求的答案。 IE。将“标准”对象嵌入到我设计的对象中。 .最后这个答案有帮助!【参考方案5】:

这只是简短的 ES5 风格的 Sayan Pal 回答的总结:

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",
    ...

【讨论】:

【参考方案6】:

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

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

【讨论】:

明智,避免使用保留字class 作为转换方法的名称!我建议改用Person.fromObject(obj) 之类的东西。【参考方案7】:

如果你愿意,这里有办法。 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));

【讨论】:

以上是关于我们可以在 javascript 中将通用对象转换为自定义对象类型吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 JavaScript 中将 JSON 对象转换为 CSV 格式

在Javascript / React中将对象转换为数组

在javascript中将字符串转换为对象数组的最佳方法?

如何在javascript中将嵌套对象转换为对象数组? [关闭]

在 JavaScript 中将数组转换为对象

如何在javascript中将字符串转换为文件对象?