Вопросы на собеседовании фронтенд-разработчика. Прототипы

[[Prototype]]

У каждого объекта в JavaScript есть внутреннее свойство, в спецификации оно обозначается [[Prototype]]. В нём хранится ссылка на другой объект.

[[Prototype]] помогает искать свойства и методы, которых нет в текущем объекте:

const utils = {
    log(message) {
        console.log(message)
    }
}

const someObj = Object.create(utils)
someObj.log('Hi!')

Если запрашиваемое свойство (через операцию [[Get]]) не получается найти в текущем объекте, то будет осуществлён переход по ссылке [[Prototype]] на другой объект и поиск продолжится в нём. Этот процесс будет продолжаться до тех пор, пока свойство не будет найдено или не завершится цепочка [[Prototype]].

По алгоритму выше работает перебор for..in (enumerable учитывается) и проверка с помощью оператора in (enumerable НЕ учитывается).

Object.prototype

Любая нормальная цепочка [[Prototype]] завершается на встроенном объекте Object.prototype.

Object.prototype — это объект, который находится в основе всех встроенных (не являющихся расширениями среды) объектов JavaScript. Содержит различные стандартные методы, используемые в JavaScript.

Свойство prototype у функций

Все функции (кроме стрелочных) по умолчанию имеют открытое и не перечисляемое свойство с названием prototype.

Это свойство указывает на произвольный объект. Объект обычно называют прототипом этой функции, т.к. мы обращаемся к нему по ссылке на свойство func.prototype.

const func = function () {}
const arrowFunc = () => {}

func.prototype // {}
arrowFunc.prototype // undefined

Каждый объект, созданный с помощью вызова функции с оператором new, будет обладать связью со свойством prototype вызванной функции:

const someObj = new func()
Object.getPrototypeOf(someObj) === func.prototype // true

Более явно можно получить такой же результат с помощью Object.create():

const anotherObj = Object.create(func.prototype)
Object.getPrototypeOf(anotherObj) === func.prototype // true

constructor

Функция конструктор — любая функция, которая вызывается с помощью new.

Объект prototype у функций по умолчанию имеет открытое неперечисляемое свойство с именем constructor. Это свойство содержит обратную ссылку на вызванную функцию.

function func() {}
func.prototype.constructor === func // true

Объект, который был создан с помощью new func(), тоже будет обладать свойством constructor (получает по цепочке [[Prototype]]). Свойство будет указывать на функцию создавшую объект.

const someObj = new func()
someObj.constructor === func // true

Про this в сконструированном объекте

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

Описанное выше поведение с цепочкой [[Prototype]] называется наследованием на основе прототипов.

Для создания связей между объектами до ES6 использовался Object.create(..). При его использовании будет всегда создаваться новый объект, а не изменяться старый. В ES6+ для этого добавили специальный метод:

Object.setPrototypeOf(
    /** кому установить */,
    /** [[Prototype]] для установки */
)

Пример:

function FirstFunc(name) {}
function SecondFunc() {}

FirstFunc.prototype.logger = function (message) {
    console.log(message)
}

Object.setPrototypeOf(SecondFunc.prototype, FirstFunc.prototype);

const secondObj = new SecondFunc()
secondObj.logger('Hi') // Hi

Оператор instanceof

Оператор instanceof используется для проверки принадлежности объекта к свойству .prototype переданной функции. Осуществляет проверку по всей цепочке [[Prototype]].

function SomeFunc() {}

const someObj = new SomeFunc()
someObj instanceof SomeFunc // true

Свойство proto

Реализуемый только в браузерах способ обращения к внутреннему свойству [[Prototype]]. Аналогичный способу получения значения через Object.getPrototypeOf(..).

function SomeFunc() {}

const someObj = new SomeFunc()
someObj.__proto__ === Object.getPrototypeOf(someObj) // true

Последние обновления

© 2023 — 2026 nbeam.ru