为什么将对象的原型设置为“Foo”不会使其成为“Foo的实例”?

Joh*_*gen 5 javascript prototype instanceof ecmascript-6

我正在尝试Object.setPrototypeOf重新设置已转换为 JSON 并返回对象的对象的原型。然而,instanceof似乎并没有按照我预期的方式工作:

class Foo {}

const obj = {};
Object.setPrototypeOf(obj, Foo);
console.log(obj instanceof Foo);
Run Code Online (Sandbox Code Playgroud)

为什么会这样呢?据我所知,instanceof工作基于将给定对象的原型与引用的类进行比较。应该有不同的方法吗?

Mat*_*wne 5

JS 类只是构造函数和原型的语法糖。Foo 是构造函数,而不是原型......所以你需要使用Foo.prototypeand not Foo

Object.setPrototypeOf({ }, Foo.prototype)
Run Code Online (Sandbox Code Playgroud)

但是,由于MDN 上的警告,我不建议您在用例中使用这种方法:

根据现代 JavaScript 引擎优化属性访问的本质,更改对象的 [[Prototype]] 是一个非常慢的操作

相反,使用Object.create()

const obj = Object.create(Foo.prototype)
Run Code Online (Sandbox Code Playgroud)

然后您可以使用Object.assign()复制数据(假设这data是您解析的 JSON 数据):

Object.assign(obj, data)
Run Code Online (Sandbox Code Playgroud)

或者,如果您的类有一个构造函数,允许您从参数设置其初始状态,您可以只使用new Foo(data),但上述方法更通用,因为它绕过了构造函数。