web-dev-qa-db-ja.com

javascriptで汎用オブジェクトをカスタムオブジェクトタイプにキャストできますか?

たとえば、コード内のどこかにすでにこのオブジェクトがあります。これは汎用オブジェクトです。

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

Personオブジェクトのコンストラクターがあります。

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

Person1をPerson型のオブジェクトに変換できる単純な構文はありますか?

51
bobo

@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

40
A1rPun

いいえ

ただし、person1オブジェクトをPersonであるかのように扱う場合、Personを使用してperson1callのプロトタイプのメソッドを呼び出すことができます。

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

ただし、getFullNameメソッドのように、Personコンストラクター内で作成された特権メソッドでは、これは明らかに機能しません。

7
Adam Rackis

これは正確な答えではなく、むしろ私の発見を共有し、できればそれに対するいくつかの重要な議論を得ることを望んでいます。

最近、自分のプロジェクトでこれを行う必要がありました。 _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]));
}
_
3
Sayan Pal

これは他のいくつかの回答からここを借りていますが、誰かを助けるかもしれないと思いました。カスタムオブジェクトで次の関数を定義すると、ジェネリックオブジェクトを渡すことができるファクトリ関数があり、クラスのインスタンスが返されます。

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);
1
Obi Onuorah

これは、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",
    ...
1
pasx

これは私のために働いた。単純なオブジェクトの場合は単純です。

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と同じ 'format'の汎用オブジェクトで動作する 'class'と呼ばれる別のコンストラクターがあります。これが誰かにも役立つことを願っています。

0
Orwol Chiles