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

и назначил ему значение 42? Теперь вызов >map.hasOwnProperty обращается к локальному свойству, в котором содержится номер, а не функция.

В таком случае прототипы только мешаются, и нам бы хотелось иметь объекты вообще без прототипов. Мы видели функцию >Object.create, что позволяет создавать объект с заданным прототипом. Мы можем передать >null для прототипа, чтобы создать свеженький объект без прототипа. Это то, что нам нужно для объектов типа >map, где могут быть любые свойства.

>var map = Object.create(null);

>map["пицца"] = 0.069;

>console.log("toString" in map);

>// → false

>console.log("пицца" in map);

>// → true

Так-то лучше! Нам уже не нужна приблуда >hasOwnProperty, потому что все свойства объекта заданы лично нами. Мы спокойно используем циклы >for/>in без оглядки на то, что люди творили с >Object.prototype.

Полиморфизм

Когда вы вызываете функцию >String, преобразующую значение в строку, для объекта, он вызовет метод >toString, чтобы создать осмысленную строчку. Я упомянул, что некоторые стандартные прототипы объявляют свои версии >toString для создания строк, более полезных, чем просто >"[object Object]".

Это простой пример мощной идеи. Когда кусок кода написан так, чтобы работать с объектами через определённый интерфейс – в нашем случае через метод >toString – любой объект, поддерживающий этот интерфейс, можно подключить к коду, и всё будет просто работать.

Такая техника называется полиморфизм, хотя никто и не меняет своей формы. Полиморфный код может работать со значениями самых разных форм, пока они поддерживают одинаковый интерфейс.

Форматируем таблицу

Давайте рассмотрим пример, чтобы понять, как выглядит полиморфизм, да и вообще объектно-ориентированное программирование. Проект следующий: мы напишем программу, которая получает массив массивов из ячеек таблицы, и строит строку, содержащую красиво отформатированную таблицу. То есть, колонки и ряды выровнены. Типа вот этого:

>name         height country

>------------ ------ -------------

>Kilimanjaro    5895 Tanzania

>Everest        8848 Nepal

>Mount Fuji     3776 Japan

>Mont Blanc     4808 Italy/France

>Vaalserberg     323 Netherlands

>Denali         6168 United States

>Popocatepetl   5465 Mexico

Работать она будет так: основная функция будет спрашивать каждую ячейку, какой она ширины и высоты, и потом использует эту информацию для определения ширины колонок и высоты рядов. Затем она попросит ячейки нарисовать себя, и соберёт результаты в одну строку.

Программа будет общаться с объектами ячеек через хорошо определённый интерфейс. Типы ячеек не будут заданы жёстко. Мы сможем добавлять новые стили ячеек – к примеру, подчёркнутые ячейки у заголовка. И если они будут поддерживать наш интерфейс, они просто заработают, без изменений в программе.