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

时间:2022-09-11 10:36:12

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类型的对象?

5 个解决方案

#1


28  

The answer of @PeterOlson may be worked back in the day but it looks like Object.create is changed. I would go for the copy-constructor way like @user166390 said in the comments.
The reason I necromanced this post is because I needed such implementation.

@PeterOlson的答案可能会在当天恢复,但看起来像Object.create已经改变。我会像@ user166390在评论中所说的那样去复制构造函数。我对这篇文章进行了暗示是因为我需要这样的实现。

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

#2


6  

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,你可以通过调用在person1上调用Person的原型上的方法:

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方法一样。

#3


3  

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

#4


1  

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

#5


0  

This is just a wrap up of Sayan Pal answer in a shorter form, ES5 style :

这只是一个简短形式的Sayan Pal回答,ES5风格:

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

#1


28  

The answer of @PeterOlson may be worked back in the day but it looks like Object.create is changed. I would go for the copy-constructor way like @user166390 said in the comments.
The reason I necromanced this post is because I needed such implementation.

@PeterOlson的答案可能会在当天恢复,但看起来像Object.create已经改变。我会像@ user166390在评论中所说的那样去复制构造函数。我对这篇文章进行了暗示是因为我需要这样的实现。

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

#2


6  

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,你可以通过调用在person1上调用Person的原型上的方法:

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方法一样。

#3


3  

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

#4


1  

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

#5


0  

This is just a wrap up of Sayan Pal answer in a shorter form, ES5 style :

这只是一个简短形式的Sayan Pal回答,ES5风格:

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