Object.setPrototypeOf()

这个Object.setPrototypeOf()静态方法设置原型(即内部[[原型]]属性)将指定对象转换为另一个对象,或无效的.

警告:更改[[原型]]从现代JavaScript引擎优化属性访问的本质来看,对象的特性是,当前每个浏览器和JavaScript引擎的操作都非常缓慢。此外,改变遗传的影响是微妙而深远的,并且不限于花在Object.setPrototypeOf(…)语句,但可以扩展到任何可以访问任何对象的代码[[原型]]已更改。您可以在中阅读更多内容JavaScript引擎基础:优化原型.

因为这个特性是语言的一部分,所以引擎开发人员仍然要负责实现这个特性的性能(理想情况下)。在引擎开发人员解决此问题之前,如果您关心性能,应避免设置[[原型]]对象的。相反,使用所需的[[原型]]使用对象.create().

试试看

语法

js公司
Object.setPrototypeOf(obj,prototype)

参数

对象

要设置其原型的对象。

原型

对象的新原型(对象或无效的).

返回值

指定的对象。

例外情况

类型错误

出现以下情况之一:

  • 这个对象参数为未定义无效的.
  • 这个对象参数为不可扩展的,或者是不可变原型外来对象,例如对象.原型窗口。但是,如果新原型的值与的原始原型的值相同,则不会引发错误对象.
  • 这个原型参数不是对象或无效的.

描述

Object.setPrototypeOf()通常认为是设置对象原型的正确方法。您应该始终使用它来支持不推荐的对象原型__原型__访问器。

如果对象参数不是对象(例如数字、字符串等),此方法不执行任何操作,无需将其强制为对象或尝试设置其原型,并直接返回对象作为原始值。如果原型与的原型值相同对象,然后对象直接返回,而不会导致类型错误即使在对象具有不可变的原型。

出于安全考虑,有些内置对象设计为具有不可变原型。这可以防止原型污染攻击,尤其是代理相关的。核心语言仅指定对象.原型作为一个不可变的原型奇异对象,其原型总是无效的。在浏览器中,窗口位置是另外两个非常常见的例子。

js公司
Object.isExtensible(Object.prototype);//真;您可以添加更多属性Object.setPrototypeOf(Object.prototype,{});//TypeError:不可变原型对象“#<object>”不能设置其原型Object.setPrototypeOf(Object.protype,null);//无错误;`Object.prototype`的原型已经`null`

示例

使用Object.setPrototypeOf()的伪经典继承

JS中使用类的继承。

js公司
类Human{}类超级英雄扩展人类{}const superMan=新的超级英雄();

然而,如果我们想实现子类而不使用,我们可以执行以下操作:

js公司
功能人员(姓名、级别){this.name=名称;this.level=级别;}函数SuperHero(名称、级别){人名(this,name,level);}Object.setPrototypeOf(超级英雄原型,人类原型);//设置`SuperHero.Prototype的`[[原型]]``//到`Human.prototype`//设置原型继承链Human.prototype.speak=功能(){return`${this.name}打招呼。`;};SuperHero.prototype.fly=函数(){return`${this.name}正在飞行。`;};const superMan=新超级英雄(“克拉克·肯特”,1);console.log(superMan.fly());console.log(superMan.speak());

经典继承(带类)和伪经典继承(含构造函数)之间的相似性原型属性)如上文所述继承链.

自函数构造函数原型属性是可写的,您可以将其重新分配给使用创建的新对象对象.create()以实现相同的继承链。使用时需要注意以下事项创建(),例如记住重新添加建造师属性。

在下面的示例中,它也使用类,超级英雄被设定为继承自人类不使用延伸通过使用setPrototypeOf()而不是。

警告:不建议使用setPrototypeOf()而不是延伸由于性能和可读性的原因。

js公司
类Human{}类超级英雄{}//设置实例属性Object.setPrototypeOf(超级英雄原型,人类原型);//连接静态属性Object.setPrototypeOf(SuperHero,Human);const superMan=新的超级英雄();

无子类延伸在中提到ES-6分类.

规格

规范
ECMAScript语言规范
#sec-object.set原型

浏览器兼容性

BCD表仅在浏览器中加载

另请参见