Как устроен JavaScript, часть 3

Эта часть статьи посвящена прототипному наследованию в JavaScript.

У объектов есть внутреннее свойство [[Prototype]] (оно доступно снаружи как __proto__), которое ссылается на “родительский” объект. При обращении к любому свойству объекта оно сперва ищется в самом объекте, а затем в его прототипе и так далее по цепочке. Как правило, данные помещаются в дочерний объект, а методы — в прототип.

При интерпретации ключевого слова function кроме собственно FunctionObject создается соответствующий функции объект-прототип. Ссылка на прототип помещается в FunctionObject.prototype.

Для создания объектов используется выражение new <FunctionName > (…). При вызове оператора new создается новый объект, в свойство [[Prototype]] записывается ссылка на FunctionObject.prototype и вызывается функция-конструктор. В ThisBinding контекста помещается ссылка на созданный объект, поэтому в конструкторе можно использовать this.

Важно различать [[Prototype]]/__proto__ и prototype. Свойство __proto__ есть у всех объектов и используется для поиска других свойств. Свойство prototype есть только у FunctionObject и используется при создании объектов через new.

Классическое наследование можно реализовать с помощью цепочки прототипов. Предположим, что от класса User необходимо “отнаследовать” класс Employee. Для этого необходимо создать функцию-конструктор Employee и вызвать конструктор “базового” класса User.

Для того, чтобы в “объектах Employee” были доступны методы “базового” класса необходимо добавить прототип User в цепочку: Employee.prototype.__proto__ = User.prototype.

Впрочем, длинные цепочки наследования в JavaScript не приветствуются.

A single golf clap? Or a long standing ovation?

By clapping more or less, you can signal to us which stories really stand out.