【问题标题】:Can we cast a generic object to a custom object type in javascript?我们可以在 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。

标签: javascript oop object


【解决方案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]));
    }
    

    【讨论】:

    【解决方案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));

      【讨论】:

        猜你喜欢
        • 2018-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-23
        • 1970-01-01
        • 1970-01-01
        • 2015-02-13
        相关资源
        最近更新 更多