简体   繁体   English

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

[英]Can we cast a generic object to a custom object type in javascript?

For example, I already have this object somewhere in the code, it is a generic object:例如,我在代码的某处已经有了这个对象,它是一个通用对象:

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

I have the constructor for a Person object:我有一个 Person 对象的构造函数:

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

Is there a simple syntax that allows us to convert person1 to an object of type Person?是否有一种简单的语法允许我们将 person1 转换为 Person 类型的对象?

The answer of @PeterOlson may be worked back in the day but it looks like Object.create is changed. @PeterOlson 的答案可能会在当天恢复,但看起来Object.create已更改。 I would go for the copy-constructor way like @user166390 said in the comments.我会选择像@user166390 在评论中所说的复制构造函数方式。
The reason I necromanced this post is because I needed such implementation.我死记硬背这篇文章的原因是因为我需要这样的实现。

Nowadays we can use Object.assign ( credits to @SayanPal solution ) & ES6 syntax:现在我们可以使用Object.assign归功于@SayanPal 解决方案)和 ES6 语法:

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

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

Usage:用法:

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

ES5 answer below ES5答案如下

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

Usage:用法:

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

Using a shorter version, 1.5 liner:使用较短的版本,1.5 衬垫:

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

jsfiddle提琴手

No.不。

But if you're looking to treat your person1 object as if it were a Person , you can call methods on Person 's prototype on person1 with call :但是,如果你正在寻找把你的person1对象,就好像它是一个Person ,你可以调用方法Person的原型上person1call

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

Though this obviously won't work for privileged methods created inside of the Person constructor—like your getFullName method.尽管这显然不适用于在 Person 构造函数内部创建的特权方法,例如您的getFullName方法。

This is not exactly an answer, rather sharing my findings, and hopefully getting some critical argument for/against it, as specifically I am not aware how efficient it is.这不完全是一个答案,而是分享我的发现,并希望得到一些支持/反对它的批判性论点,因为我不知道它的效率如何。

I recently had a need to do this for my project.我最近需要为我的项目执行此操作。 I did this using Object.assign , more precisely it is done something like this: Object.assign(new Person(...), anObjectLikePerson) .我使用Object.assign做到了这一点,更准确地说,它是这样做的: Object.assign(new Person(...), anObjectLikePerson)

Here is link to my JSFiddle , and also the main part of the code:这是我的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]));
}

This borrows from a few other answers here but I thought it might help someone.这借鉴了这里的其他一些答案,但我认为它可能对某人有所帮助。 If you define the following function on your custom object, then you have a factory function that you can pass a generic object into and it will return for you an instance of the class.如果您在自定义对象上定义了以下函数,那么您就有了一个工厂函数,您可以将一个通用对象传递给它,它会为您返回一个类的实例。

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

    return field;
}

Use like this像这样使用

var typedObj = CustomObject.create(genericObj);

This is just a wrap up of Sayan Pal answer in a shorter form, ES5 style :这只是以更短的形式,ES5 风格对 Sayan Pal 答案的总结:

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

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

I like it because it is the closest to the very neat object initialisation in .Net:我喜欢它,因为它最接近 .Net 中非常简洁的对象初始化:

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

This worked for me.这对我有用。 It's simple for simple objects.对于简单的对象,这很简单。

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

I was also searching for a simple solution, and this is what I came up with, based on all other answers and my research.我也在寻找一个简单的解决方案,这就是我根据所有其他答案和我的研究提出的。 Basically, class Person has another constructor, called 'class' which works with a generic object of the same 'format' as Person .基本上,类Person有另一个构造,称为“类”与相同的“格式”作为的一般对象的工作。 I hope this might help somebody as well.我希望这也可以帮助某人。

Here have a way if you like.如果你愿意,这里有一个方法。 1st make an object with your all desire properties. 1st 用你所有想要的属性制作一个对象。 Then Call this object with your custom values.然后使用您的自定义值调用此对象。 Here is link to the JSFiddle , and also the main part of the这是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));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM