从 JSON 结果创建 ES6 class 的实例

Create instance of ES6 class from JSON result

从 JSON 对象创建 ES6 class 实例的最简单方法是什么?例如,给定如下内容:

class Foo
  constructor(bar) {
    this.bar = bar
  }
  frob() {
    console.log(`frobbed ${this.bar}`)
  }
}

和一个 API 调用返回:

{ "bar": "baz" }

我怎样才能得到类似这样的东西?

let foo = new Foo("baz")

即,类似于:

async function frobResult() {
  let result = await fetch('/foo') // returns { "bar": "baz" }
  
  // ...magic happens here?

  result.frob()                    // logs "frobbed baz" to console
}

显然我可以让构造函数获取 JSON 对象并从中拉出 bar,或者编写一个工厂函数来做类似的事情,但我宁愿不必调用每个 属性 按名称输出,理想情况下我宁愿不必循环 getOwnPropertyNames() 或类似的。有没有什么办法,例如,我可以通过猴子修补 JSON 对象来扩展 Foo?


ETA: 在答案中, Object.setPrototypeOf() is the exact monkey-patch solution I was asking for, but Object.assign() 当您不仅有一个 class,还有一个复杂的对象时特别有用具有您不想丢失的自己的状态,例如 Vue 组件。

使用Object.create创建一个对象,其内部原型为Foo.prototype,其自身属性为API对象的:

class Foo {
  constructor(bar) {
    this.bar = bar
  }
  frob() {
    console.log(`frobbed ${this.bar}`)
  }
}
const apiObj = { "bar": "baz" };

const instance = Object.assign(Object.create(Foo.prototype), apiObj);
console.log(instance);
instance.frob();

您可以将对象或其属性传递给构造函数。

async function frobResult() {
  const result = await fetch('/foo') // returns { "bar": "baz" }
  // ...magic happens here?
  const foo = new Foo(result.bar);
  foo.frob()                    // logs "frobbed baz" to console
}

使用Object.setPrototypeOf()方法将result对象的原型设置为Foo对象的原型。

class Foo {
  constructor(bar) {
    this.bar = bar
  }
  frob() {
    console.log(`frobbed ${this.bar}`);
  }
}

function frobResult() {
  let result = { bar: "baz" }; // Mock fetch api result
  Object.setPrototypeOf(result, Foo.prototype);
  console.log(result);
  result.frob();
}

frobResult();