Что такое прототип в js
Перейти к содержимому

Что такое прототип в js

  • автор:

prototype js что это

Прототип — это объект, который используется для наследования свойств и методов.

  • Создадим класс Car , который будет содержать свойства model и year , и метод start() :
function Car(model, year)  this.model = model; this.year = year; > Car.prototype.start = function ()  console.log('Engine started'); >; 

Мы создали функцию-конструктор Car , которая принимает модель и год выпуска автомобиля и сохраняет их в свойства объекта. Затем мы добавили метод start() в прототип объекта Car .

  • Теперь создадим объект honda , используя оператор new :
var honda = new Car('Civic', 2020); 

Мы создали объект honda на основе класса Car с помощью оператора new. honda наследует свойства и методы от прототипа Car .

Мы можем вызвать метод start() на объекте honda :

honda.start(); // выведет "Engine started" 

Также мы можем добавить новый метод в прототип Car :

Car.prototype.stop = function ()  console.log('Engine stopped'); >; 
  • Теперь мы можем вызвать новый метод stop() на объекте honda :
honda.stop(); // выведет "Engine stopped" 

Таким образом, мы использовали прототип для наследования свойств и методов от класса Car для объекта honda .

Прототип объекта

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/prototype-inheritance.

Объекты в JavaScript можно организовать в цепочки так, чтобы свойство, не найденное в одном объекте, автоматически искалось бы в другом.

Связующим звеном выступает специальное свойство __proto__ .

Прототип proto

Если один объект имеет специальную ссылку __proto__ на другой объект, то при чтении свойства из него, если свойство отсутствует в самом объекте, оно ищется в объекте __proto__ .

Свойство __proto__ доступно во всех браузерах, кроме IE10-, а в более старых IE оно, конечно же, тоже есть, но напрямую к нему не обратиться, требуются чуть более сложные способы, которые мы рассмотрим позднее.

Пример кода (кроме IE10-):

var animal = < eats: true >; var rabbit = < jumps: true >; rabbit.__proto__ = animal; // в rabbit можно найти оба свойства alert( rabbit.jumps ); // true alert( rabbit.eats ); // true
  1. Первый alert здесь работает очевидным образом – он выводит свойство jumps объекта rabbit .
  2. Второй alert хочет вывести rabbit.eats , ищет его в самом объекте rabbit , не находит – и продолжает поиск в объекте rabbit.__proto__ , то есть, в данном случае, в animal .

Иллюстрация происходящего при чтении rabbit.eats (поиск идёт снизу вверх):

Объект, на который указывает ссылка __proto__ , называется «прототипом». В данном случае получилось, что animal является прототипом для rabbit .

Также говорят, что объект rabbit «прототипно наследует» от animal .

Обратим внимание – прототип используется исключительно при чтении. Запись значения, например, rabbit.eats = value или удаление delete rabbit.eats – работает напрямую с объектом.

В примере ниже мы записываем свойство в сам rabbit , после чего alert перестаёт брать его у прототипа, а берёт уже из самого объекта:

var animal = < eats: true >; var rabbit = < jumps: true, eats: false >; rabbit.__proto__ = animal; alert( rabbit.eats ); // false, свойство взято из rabbit

Другими словами, прототип – это «резервное хранилище свойств и методов» объекта, автоматически используемое при поиске.

У объекта, который является __proto__ , может быть свой __proto__ , у того – свой, и так далее. При этом свойства будут искаться по цепочке.

Ссылка proto в спецификации

Если вы будете читать спецификацию ECMAScript – свойство __proto__ обозначено в ней как [[Prototype]] .

Двойные квадратные скобки здесь важны, чтобы не перепутать его с совсем другим свойством, которое называется prototype , и которое мы рассмотрим позже.

Метод hasOwnProperty

Обычный цикл for..in не делает различия между свойствами объекта и его прототипа.

Он перебирает всё, например:

var animal = < eats: true >; var rabbit = < jumps: true, __proto__: animal >; for (var key in rabbit) < alert( key + " = " + rabbit[key] ); // выводит и "eats" и "jumps" >

Иногда хочется посмотреть, что находится именно в самом объекте, а не в прототипе.

Вызов obj.hasOwnProperty(prop) возвращает true , если свойство prop принадлежит самому объекту obj , иначе false .

var animal = < eats: true >; var rabbit = < jumps: true, __proto__: animal >; alert( rabbit.hasOwnProperty('jumps') ); // true: jumps принадлежит rabbit alert( rabbit.hasOwnProperty('eats') ); // false: eats не принадлежит

Для того, чтобы перебрать свойства самого объекта, достаточно профильтровать key через hasOwnProperty :

var animal = < eats: true >; var rabbit = < jumps: true, __proto__: animal >; for (var key in rabbit) < if (!rabbit.hasOwnProperty(key)) continue; // пропустить "не свои" свойства alert( key + " = " + rabbit[key] ); // выводит только "jumps" >

Object.create(null)

Зачастую объекты используют для хранения произвольных значений по ключу, как коллекцию:

var data = <>; data.text = "Привет"; data.age = 35; // . 

При дальнейшем поиске в этой коллекции мы найдём не только text и age , но и встроенные функции:

var data = <>; alert(data.toString); // функция, хотя мы её туда не записывали

Это может быть неприятным сюрпризом и приводить к ошибкам, если названия свойств приходят от посетителя и могут быть произвольными.

Чтобы этого избежать, мы можем исключать свойства, не принадлежащие самому объекту:

var data = <>; // выведет toString только если оно записано в сам объект alert(data.hasOwnProperty('toString') ? data.toString : undefined);

Однако, есть путь и проще:

var data = Object.create(null); data.text = "Привет"; alert(data.text); // Привет alert(data.toString); // undefined

Объект, создаваемый при помощи Object.create(null) не имеет прототипа, а значит в нём нет лишних свойств. Для коллекции – как раз то, что надо.

Методы для работы с proto

В современных браузерах есть два дополнительных метода для работы с __proto__ . Зачем они нужны, если есть __proto__ ? В общем-то, не очень нужны, но по историческим причинам тоже существуют.

Чтение: Object.getPrototypeOf(obj) Возвращает obj.__proto__ (кроме IE8-) Запись: Object.setPrototypeOf(obj, proto) Устанавливает obj.__proto__ = proto (кроме IE10-).

Кроме того, есть ещё один вспомогательный метод:

Создание объекта с прототипом: Object.create(proto, descriptors) Создаёт пустой объект с __proto__ , равным первому аргументу (кроме IE8-), второй необязательный аргумент может содержать дескрипторы свойств.

Итого

  • В JavaScript есть встроенное «наследование» между объектами при помощи специального свойства __proto__ .
  • При установке свойства rabbit.__proto__ = animal говорят, что объект animal будет «прототипом» rabbit .
  • При чтении свойства из объекта, если его в нём нет, оно ищется в __proto__ . Прототип задействуется только при чтении свойства. Операции присвоения obj.prop = или удаления delete obj.prop совершаются всегда над самим объектом obj .

Несколько прототипов одному объекту присвоить нельзя, но можно организовать объекты в цепочку, когда один объект ссылается на другой при помощи __proto__ , тот ссылается на третий, и так далее.

В современных браузерах есть методы для работы с прототипом:

  • Object.getPrototypeOf(obj) (кроме IE8-)
  • Object.setPrototypeOf(obj, proto) (кроме IE10-)
  • Object.create(proto, descriptors) (кроме IE8-)

Возможно, вас смущает недостаточная поддержка __proto__ в старых IE. Но это не страшно. В последующих главах мы рассмотрим дополнительные методы работы с __proto__ , включая те, которые работают везде.

Также мы рассмотрим, как свойство __proto__ используется внутри самого языка JavaScript и как организовать классы с его помощью.

Наследование и цепочка прототипов

Модель наследования в JavaScript может озадачить опытных разработчиков на высокоуровневых объектно-ориентированных языках (таких, например, как Java или C++), поскольку она динамическая и не включает в себя реализацию понятия class (хотя ключевое слово class , бывшее долгие годы зарезервированным, и приобрело практическое значение в стандарте ES2015, однако, классы в JavaScript представляют собой лишь «синтаксический сахар» поверх прототипно-ориентированной модели наследования).

В плане наследования JavaScript работает лишь с одной сущностью: объектами. Каждый объект имеет внутреннюю ссылку на другой объект, называемый его прототипом. У объекта-прототипа также есть свой собственный прототип и так далее до тех пор, пока цепочка не завершится объектом, у которого свойство prototype равно null . По определению, null не имеет прототипа и является завершающим звеном в цепочке прототипов.

Хотя прототипную модель наследования некоторые относят к недостаткам JavaScript, на самом деле она мощнее классической. К примеру, поверх неё можно предельно просто реализовать классическое наследование, а вот попытки совершить обратное непременно вынудят вас попотеть.

Наследование с цепочкой прототипов

Наследование свойств

Объекты в JavaScript — динамические «контейнеры», наполненные свойствами (называемыми собственными свойствами). Каждый объект содержит ссылку на свой объект-прототип. При попытке получить доступ к какому-либо свойству объекта, свойство вначале ищется в самом объекте, затем в прототипе объекта, после чего в прототипе прототипа, и так далее. Поиск ведётся до тех пор, пока не найдено свойство с совпадающим именем или не достигнут конец цепочки прототипов.

// В этом примере someObject.[[Prototype]] означает прототип someObject. // Это упрощённая нотация (описанная в стандарте ECMAScript). // Она не может быть использована в реальных скриптах. // Допустим, у нас есть объект 'o' с собственными свойствами a и b // // o.[[Prototype]] имеет свойства b и с // // Далее, o.[[Prototype]].[[Prototype]] является null // null - это окончание в цепочке прототипов // по определению, null не имеет свойства [[Prototype]] // В итоге полная цепочка прототипов выглядит так: // ---> ---> null console.log(o.a); // 1 // Есть ли у объекта 'o' собственное свойство 'a'? // Да, и его значение равно 1 console.log(o.b); // 2 // Есть ли у объекта 'o' собственное свойство 'b'? // Да, и его значение равно 2. // У прототипа o.[[Prototype]] также есть свойство 'b', // но обращения к нему в данном случае не происходит. // Это и называется "property shadowing" (затенение свойства) console.log(o.c); // 4 // Есть ли у объекта 'o' собственное свойство 'с'? // Нет, тогда поищем его в прототипе. // Есть ли у объекта o.[[Prototype]] собственное свойство 'с'? // Да, оно равно 4 console.log(o.d); // undefined // Есть ли у объекта 'o' собственное свойство 'd'? // Нет, тогда поищем его в прототипе. // Есть ли у объекта o.[[Prototype]] собственное свойство 'd'? // Нет, продолжаем поиск по цепочке прототипов. // o.[[Prototype]].[[Prototype]] равно null, прекращаем поиск, // свойство не найдено, возвращаем undefined 

При добавлении к объекту нового свойства, создаётся новое собственное свойство. Единственным исключением из этого правила являются наследуемые свойства, имеющие getter или setter.

Наследование «методов»

JavaScript не имеет «методов» в смысле, принятом в классической модели ООП. В JavaScript любая функция может быть добавлена к объекту в виде его свойства. Унаследованная функция ведёт себя точно так же, как любое другое свойство объекта, в том числе и в плане «затенения свойств» (property shadowing), как показано в примере выше (в данном конкретном случае это форма переопределения метода — method overriding).

При выполнении унаследованной функции значение this (/ru/docs/Web/JavaScript/Reference/Operators/this) указывает на объект-потомок, а не на прототип, в котором функция является собственным свойством.

var o =  a: 2, m: function ()  return this.a + 1; >, >; console.log(o.m()); // 3 // в этом случае при вызове 'o.m' this указывает на 'o' var p = Object.create(o); // 'p' - потомок 'o' p.a = 12; // создаст собственное свойство 'a' объекта 'p' console.log(p.m()); // 13 // при вызове 'p.m' this указывает на 'p'. // т.е. когда 'p' наследует функцию 'm' объекта 'o', // this.a означает 'p.a', собственное свойство 'a' объекта 'p' 

Различные способы создания объектов и получаемые в итоге цепочки прототипов

Создание объектов с помощью литералов

var o =  a: 1 >; // Созданный объект 'o' имеет Object.prototype в качестве своего [[Prototype]] // у 'o' нет собственного свойства 'hasOwnProperty' // hasOwnProperty — это собственное свойство Object.prototype. // Таким образом 'o' наследует hasOwnProperty от Object.prototype // Object.prototype в качестве прототипа имеет null. // o ---> Object.prototype ---> null var a = ["yo", "whadup", "?"]; // Массивы наследуются от Array.prototype // (у которого есть такие методы, как indexOf, forEach и т.п.). // Цепочка прототипов при этом выглядит так: // a ---> Array.prototype ---> Object.prototype ---> null function f()  return 2; > // Функции наследуются от Function.prototype // (у которого есть такие методы, как call, bind и т.п.): // f ---> Function.prototype ---> Object.prototype ---> null 

Создание объектов с помощью конструктора

В JavaScript «конструктор» — это «просто» функция, вызываемая с оператором new.

function Graph()  this.vertexes = []; this.edges = []; > Graph.prototype =  addVertex: function (v)  this.vertexes.push(v); >, >; var g = new Graph(); // объект 'g' имеет собственные свойства 'vertexes' и 'edges'. // g.[[Prototype]] принимает значение Graph.prototype при выполнении new Graph(). 

Object.create

В ECMAScript 5 представлен новый метод создания объектов: Object.create. Прототип создаваемого объекта указывается в первом аргументе этого метода:

var a =  a: 1 >; // a ---> Object.prototype ---> null var b = Object.create(a); // b ---> a ---> Object.prototype ---> null console.log(b.a); // 1 (унаследовано) var c = Object.create(b); // c ---> b ---> a ---> Object.prototype ---> null var d = Object.create(null); // d ---> null console.log(d.hasOwnProperty); // undefined, т.к. 'd' не наследуется от Object.prototype 

Используя ключевое слово class

С выходом ECMAScript 6 появился целый набор ключевых слов, реализующих классы. Они могут показаться знакомыми людям, изучавшим языки, основанные на классах, но есть существенные отличия. JavaScript был и остаётся прототипно-ориентированным языком. Новые ключевые слова: » class «, » constructor «, » static «, » extends » и » super «.

"use strict"; class Polygon  constructor(height, width)  this.height = height; this.width = width; > > class Square extends Polygon  constructor(sideLength)  super(sideLength, sideLength); > get area()  return this.height * this.width; > set sideLength(newLength)  this.height = newLength; this.width = newLength; > > var square = new Square(2); 

Производительность

Длительное время поиска свойств, располагающихся относительно высоко в цепочке прототипов, может негативно сказаться на производительности (performance), особенно в критических в этом смысле местах кода. Кроме того, попытка найти несуществующие свойства неизбежно приведёт к проверке на их наличие у всех объектов цепочки прототипов.

Кроме того, при циклическом переборе свойств объекта будет обработано каждое свойство, присутствующее в цепочке прототипов.

Если вам необходимо проверить, определено ли свойство у самого объекта, а не где-то в его цепочке прототипов, вы можете использовать метод hasOwnProperty , который все объекты наследуют от Object.prototype .

hasOwnProperty — единственная существующая в JavaScript возможность работать со свойствами, не затрагивая цепочку прототипов.

Примечание: Примечание: Для проверки существования свойства недостаточно проверять, эквивалентно ли оно undefined . Свойство может вполне себе существовать, но при этом ему может быть присвоено значение undefined .

Плохая практика: расширение базовых прототипов

Одной из частых ошибок является расширение Object.prototype или других базовых прототипов.

Такой подход называется monkey patching и нарушает принцип инкапсуляции. Несмотря на то, что ранее он использовался в таких широко распространённых фреймворках, как например, Prototype.js, в настоящее время не существует разумных причин для его использования, поскольку в данном случае встроенные типы «захламляются» дополнительной нестандартной функциональностью.

Единственным оправданием расширения базовых прототипов могут являться лишь полифилы — эмуляторы новой функциональности (например, Array.forEach) для не поддерживающих её реализаций языка в старых веб-браузерах.

Примеры

B наследует от A :

function A(a)  this.varA = a; > // What is the purpose of including varA in the prototype when A.prototype.varA will always be shadowed by // this.varA, given the definition of function A above? A.prototype =  varA: null, // Shouldn't we strike varA from the prototype as doing nothing? // perhaps intended as an optimization to allocate space in hidden classes? // https://developers.google.com/speed/articles/optimizing-javascript#Initializing instance variables // would be valid if varA wasn't being initialized uniquely for each instance doSomething: function ()  // . >, >; function B(a, b)  A.call(this, a); this.varB = b; > B.prototype = Object.create(A.prototype,  varB:  value: null, enumerable: true, configurable: true, writable: true, >, doSomething:  value: function ()  // переопределение A.prototype.doSomething.apply(this, arguments); // call super // . >, enumerable: true, configurable: true, writable: true, >, >); B.prototype.constructor = B; var b = new B(); b.doSomething(); 
  • Типы определяются в .prototype
  • Для наследования используется Object.create()

prototype и Object.getPrototypeOf

Как уже упоминалось, JavaScript может запутать разработчиков на Java или C++, ведь в нём совершенно нет «нормальных» классов. Всё, что мы имеем — лишь объекты. Даже те «classes», которые мы имитировали в статье, тоже являются функциональными объектами.

Вы наверняка заметили, что у function A есть особое свойство prototype . Это свойство работает с оператором new . Ссылка на объект-прототип копируется во внутреннее свойство [[Prototype]] нового объекта. Например, в этом случае var a1 = new A() , JavaScript (после создания объекта в памяти и до выполнения функции function A() ) устанавливает a1.[[Prototype]] = A.prototype . Потом, при попытке доступа к свойству нового экземпляра объекта, JavaScript проверяет, принадлежит ли свойство непосредственно объекту. Если нет, то интерпретатор ищет в свойстве [[Prototype]] . Всё, что было определено в prototype, в равной степени доступно и всем экземплярам данного объекта. При внесении изменений в prototype все эти изменения сразу же становятся доступными и всем экземплярам объекта.

[[Prototype]] работает рекурсивно, то есть при вызове:

var o = new Foo(); 

JavaScript на самом деле выполняет что-то подобное:

Object.prototype.__proto__

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

Предупреждение: хотя на сегодняшний момент большинство браузеров поддерживают свойство Object.prototype.__proto__ , его поведение только недавно было стандартизировано в новой спецификации ECMAScript 6. Если вам требуется поддержка браузеров до этой спецификации, рекомендуется использовать вместо него метод Object.getPrototypeOf() .

Сводка

Свойство __proto__ объекта Object.prototype (en-US) является свойством доступа (комбинацией геттера и сеттера), которое расширяет внутренний прототип [[Prototype]] объекта (являющийся объектом или null ), через который осуществлялся доступ.

Использование свойства __proto__ вызывает споры и многих оно разочаровало. Ранее оно никогда не включалось в спецификацию EcmaScript, но современные браузеры всё равно решили его реализовать. Сегодня свойство __proto__ стандартизировано в спецификации ECMAScript 6 и будет поддерживаться в будущем. Тем не менее, изменение прототипа [[Prototype]] объекта всё ещё остаётся медленной операцией, которую следует избегать, если вы беспокоитесь о производительности.

Свойство __proto__ также может использоваться при определении литерала объекта, устанавливая прототип [[Prototype]] объекта при его создании. Этот способ может рассматриваться как альтернатива методу Object.create() . Смотрите также литеральный синтаксис инициализации объекта.

Синтаксис

var shape = >, circle = new Circle(); // Установка прототипа объекта shape.__proto__ = circle; // Получение прототипа объекта console.log(shape.__proto__ === circle); // true 

Обратите внимание: название свойства состоит из двух подчёркиваний, следующих за ними пяти символов «proto» и следующих за ними ещё двух подчёркиваний.

Описание

Геттер свойства __proto__ расширяет значение внутреннего прототипа [[Prototype]] объекта. Для объектов, созданных с использованием литеральной формы создания объекта, это значение равно Object.prototype (en-US). Для функций это значение равно Function.prototype (en-US). Для объектов, созданных с использованием формы new fun , где fun является одной из встроенных функций-конструкторов, предоставляемых JavaScript ( Array , Boolean , Date , Number , Object , String и так далее — включая новые конструкторы, добавленные в процессе развития JavaScript), это значение равно fun.prototype . Для объектов, созданных с использованием формы new fun , где fun является функцией, определённой в скрипте, это значение равно значению fun.prototype во время вычисления new fun . Именно поэтому при присваивании fun.prototype нового значения, ранее созданные экземпляры fun продолжат использовать предыдущее значение в качестве своего прототипа [[Prototype]] , а последующие вызовы new fun будут использовать вновь присвоенное значение в качестве своего прототипа [[Prototype]] .

Геттер __proto__ позволяет прототипу [[Prototype]] объекта быть изменяемым. Объект должен быть расширяемым в соответствии с Object.isExtensible() : если это не так, выкидывается исключение TypeError . Предоставляемое значение должно быть объектом или null . Предоставление любого другого значения ничего не даст.

Для понимания того, как прототипы используются для наследования, смотрите статью руководства «Наследование и цепочки прототипов».

Свойство __proto__ является простым свойством доступа на объекте Object.prototype (en-US) — свойством, состоящим из геттера и сеттера. Свойство __proto__ будет найдено, если, в конечном итоге, его поиск пройдёт через Object.prototype (en-US), но при доступе к нему не через Object.prototype (en-US), оно найдено не будет. Если перед просмотром Object.prototype (en-US) буден найдено какое-нибудь другое свойство __proto__ , оно скроет искомое свойство Object.prototype (en-US).

var noProto = Object.create(null); console.log(typeof noProto.__proto__); // undefined console.log(Object.getPrototypeOf(noProto)); // null noProto.__proto__ = 17; console.log(noProto.__proto__); // 17 console.log(Object.getPrototypeOf(noProto)); // null var protoHidden = >; Object.defineProperty(protoHidden, "__proto__",  value: 42, writable: true, configurable: true, enumerable: true, >); console.log(protoHidden.__proto__); // 42 console.log(Object.getPrototypeOf(protoHidden) === Object.prototype); // true 

Примеры

В следующем примере создаётся новый экземпляр Employee , а затем проверяется, что его свойство __proto__ является тем же самым объектом, что и его конструктор prototype .

// Декларируем функцию, используемую как конструктор function Employee()  /* инициализируем экземпляр */ > // Создаём новый экземпляр Employee var fred = new Employee(); // Проверка на эквивалентность fred.__proto__ === Employee.prototype; // true 

В этот момент fred унаследован от Employee , однако присваивание другого объекта в fred.__proto__ может изменить это:

function Cow()  /* инициализируем экземпляр */ > // Присваиваем __proto__ новый объект fred.__proto__ = Cow.prototype; 

Теперь fred наследуется непосредственно от Cow.prototype , а не от Employee.prototype , и теряет свойства, изначально унаследованные от Employee.prototype .

Однако, это применяется только к расширяемым объектам, у нерасширяемых объектов свойство __proto__ не может быть изменено:

var obj = >; Object.preventExtensions(obj); obj.__proto__ = >; // выкинет TypeError 

Обратите внимание, что свойство __proto__ может быть переопределено даже у объекта Object.prototype , если новая цепочка заканчивается null :

var b = >; Object.prototype.__proto__ = Object.create( null, // [[Prototype]]  hi:  value: function ()  alert("hi"); >, >, >, ); b.hi(); 

Если свойство __proto__ объекта Object.prototype (en-US) не установлено в null , или в другой объект, чья цепочка прототипов, в конечном итоге, явно не заканчивается значением null , будет выкинуто исключение TypeError «циклическое значение __proto__», поскольку цепочка должна заканчиваться null (как это и происходит на Object.prototype (en-US) при нормальных обстоятельствах).

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

Specification
ECMAScript Language Specification
# sec-object.prototype.__proto__

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

BCD tables only load in the browser

Примечание: спецификация ES6 требует поддержку свойства __proto__ только в браузерах и не требует его поддержку в других окружениях (хотя оно и рекомендуется в качестве обязательного). Если ваш код должен работать в не-браузерных окружениях, вместо свойства рекомендуется использовать методы Object.getPrototypeOf() и Object.setPrototypeOf() .

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

  • Object.prototype.isPrototypeOf()
  • Object.getPrototypeOf()
  • Object.setPrototypeOf()

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 20 янв. 2024 г. by MDN contributors.

Your blueprint for a better internet.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *