Выразительный JavaScript (Хавербеке) - страница 68

является экземпляром >TextCell, поскольку >RTextCell.prototype происходит от >TextCell.prototype. Оператор также можно применять к стандартным конструкторам типа >Array. Практически все объекты – экземпляры >Object.

Итог

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

Конструкторы – функции, имена которых обычно начинаются с заглавной буквы – можно использовать с оператором >new для создания объектов. Прототипом нового объекта будет объект, содержащийся в свойстве >prototype конструктора. Это можно использовать, помещая в прототип свойства, общие для всех экземпляров данного типа. Оператор >instanceof, если ему дать объект и конструктор, может сказать, является ли объект экземпляром этого конструктора.

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

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

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

Упражнения

Векторный тип

Напишите конструктор >Vector, представляющий вектор в двумерном пространстве. Он принимает параметры >x и >y (числа), которые хранятся в одноимённых свойствах.

Дайте прототипу >Vector два метода, >plus и >minus, которые принимают другой вектор в качестве параметра и возвращают новый вектор, который хранит в >x и >y сумму или разность двух векторов (один >this, второй – аргумент).

Добавьте геттер >length в прототип, подсчитывающий длину вектора – расстояние от (0, 0) до (x, y).

>// Ваш код


>console.log(new Vector(1, 2).plus(new Vector(2, 3)));

>// → Vector{x: 3, y: 5}

>console.log(new Vector(1, 2).minus(new Vector(2, 3)));

>// → Vector{x: -1, y: -1}

>console.log(new Vector(3, 4).length);

>// → 5

Ещё одна ячейка

Создайте тип ячейки >StretchCell(inner, width, height), соответствующий интерфейсу ячеек таблицы из этой главы. Он должен оборачивать другую ячейку (как делает