This page was translated from English by the community. Learn more and join the MDN Web Docs community.

View in English Always switch to English

Object.setPrototypeOf()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since ⁨сентябрь 2015 г.⁩.

Предупреждение: Изменение прототипа [[Prototype]] объекта является, по самой природе оптимизации доступа к свойствам в современных движках JavaScript, очень медленной операцией, это справедливо для любого браузера и движка JavaScript. Изменение прототипов очень тонко и обширно влияет на производительность, причём это влияние не ограничивается просто временем, проведённым внутри метода Object.setPrototypeOf(), оно может распространяться на любой код, который имеет доступ к любому объекту, чей прототип [[Prototype]] был изменён. Если вы заботитесь о производительности, вы никогда не должны изменять прототип [[Prototype]] объекта. Вместо этого создайте объект с нужным прототипом [[Prototype]], с помощью метода Object.create().

Сводка

Метод Object.setPrototypeOf() устанавливает прототип (то есть, внутреннее свойство [[Prototype]]) указанного объекта в другой объект или null.

Синтаксис

Object.setPrototypeOf(obj, prototype);

Параметры

obj

Объект, которому устанавливается прототип.

prototype

Новый прототип объекта (объект или null).

Описание

Выкидывает исключение TypeError, если объект, чей прототип [[Prototype]] является не расширяемым, согласно методу Object.isExtensible(). Не делает ничего, если параметр prototype не является объектом или значением null (то есть, является числом, строкой, логическим значением или undefined). В противном случае метод устанавливает прототип [[Prototype]] объекта obj в новое значение.

Примеры

js
var dict = Object.setPrototypeOf({}, null);

Полифил

Используя старое свойство Object.prototype.__proto__, мы можем легко определить Object.setPrototypeOf(), если он ещё не доступен:

js
if (!Object.setPrototypeOf) {
  Object.prototype.setPrototypeOf = function (obj, proto) {
    if (obj.__proto__) {
      obj.__proto__ = proto;
      return obj;
    } else {
      // Если нужно будет определить прототип у Object.create(null) объекта
      var Fn = function () {
        for (var key in obj) {
          //Если в объект уже были определены некоторые свойства
          Object.defineProperty(this, key, {
            value: obj[key],
          });
        }
      };
      Fn.prototype = proto;
      return new Fn();
    }
  };
}

Добавление цепочки прототипов

Сочетание метода Object.getPrototypeOf() и свойства Object.prototype.__proto__ позволяет добавить целую цепочку прототипов к новому прототипу объекта:

js
/**
 *** Object.appendChain(@object, @prototype)
 *
 * Присоединяет первый неродной прототип цепочки к новому прототипу.
 * Возвращает @object (если он был примитивным значением, оно будет преобразовано в объект).
 *
 *** Object.appendChain(@object [, "@arg_name_1", "@arg_name_2", "@arg_name_3", "..."], "@function_body")
 *** Object.appendChain(@object [, "@arg_name_1, @arg_name_2, @arg_name_3, ..."], "@function_body")
 *
 * Присоединяет первый не родной прототип цепочки к родному объекту Function.prototype, затем присоединяет
 * new Function(["@arg"(s)], "@function_body") к этой цепочке.
 * Возвращает функцию.
 *
 **/

Object.appendChain = function (oChain, oProto) {
  if (arguments.length < 2) {
    throw new TypeError("Object.appendChain - Not enough arguments");
  }
  if (typeof oProto === "number" || typeof oProto === "boolean") {
    throw new TypeError(
      "second argument to Object.appendChain must be an object or a string",
    );
  }

  var oNewProto = oProto,
    oReturn =
      (o2nd =
      oLast =
        oChain instanceof this ? oChain : new oChain.constructor(oChain));

  for (
    var o1st = this.getPrototypeOf(o2nd);
    o1st !== Object.prototype && o1st !== Function.prototype;
    o1st = this.getPrototypeOf(o2nd)
  ) {
    o2nd = o1st;
  }

  if (oProto.constructor === String) {
    oNewProto = Function.prototype;
    oReturn = Function.apply(null, Array.prototype.slice.call(arguments, 1));
    this.setPrototypeOf(oReturn, oLast);
  }

  this.setPrototypeOf(o2nd, oNewProto);
  return oReturn;
};

Использование

Первый пример: присоединение цепочки к прототипу

js
function Mammal() {
  this.isMammal = "да";
}

function MammalSpecies(sMammalSpecies) {
  this.species = sMammalSpecies;
}

MammalSpecies.prototype = new Mammal();
MammalSpecies.prototype.constructor = MammalSpecies;

var oCat = new MammalSpecies("Felis");

alert(oCat.isMammal); // 'да'

function Animal() {
  this.breathing = "да";
}

Object.appendChain(oCat, new Animal());

alert(oCat.breathing); // 'да'

Второй пример: преобразование примитивного значения в экземпляр его конструктора и присоединение его цепочки к прототипу

js
function Symbol() {
  this.isSymbol = "да";
}

var nPrime = 17;

alert(typeof nPrime); // 'number'

var oPrime = Object.appendChain(nPrime, new Symbol());

alert(oPrime); // '17'
alert(oPrime.isSymbol); // 'да'
alert(typeof oPrime); // 'object'

Третий пример: присоединение цепочки к объекту Function.prototype и новой функции к этой цепочке

js
function Person(sName) {
  this.identity = sName;
}

var george = Object.appendChain(
  new Person("Георг"),
  'alert("Привет, парни!!");',
);

alert(george.identity); // 'Георг'
george(); // 'Привет, парни!!'

Спецификации

Specification
ECMAScript® 2026 Language Specification
# sec-object.setprototypeof

Совместимость с браузерами

Смотрите также