Марейн Хавербеке - Выразительный JavaScript

Тут можно читать онлайн Марейн Хавербеке - Выразительный JavaScript - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.

Марейн Хавербеке - Выразительный JavaScript краткое содержание

Выразительный JavaScript - описание и краткое содержание, автор Марейн Хавербеке, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

В процессе чтения вы познакомитесь с основами программирования и, в частности, языка JavaScript, а также выполните несколько небольших проектов. Один из самых интересных проектов — создание своего языка программирования.

Выразительный JavaScript - читать онлайн бесплатно полную версию (весь текст целиком)

Выразительный JavaScript - читать книгу онлайн бесплатно, автор Марейн Хавербеке
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

function repeat(string, times) {

var result = "";

for (var i = 0; i < times; i++)

result += string;

return result;

}

function TextCell(text) {

this.text = text.split("\n");

}

TextCell.prototype.minWidth = function() {

return this.text.reduce(function(width, line) {

return Math.max(width, line.length);

}, 0);

};

TextCell.prototype.minHeight = function() {

return this.text.length;

};

TextCell.prototype.draw = function(width, height) {

var result = [];

for (var i = 0; i < height; i++) {

var line = this.text[i] || "";

result.push(line + repeat(" ", width - line.length));

}

return result;

};

В коде используется вспомогательная функция repeat, которая возвращает переданную первым аргументом строку, повторённую переданное вторым аргументом количество раз. Метод drawиспользует её для создания отступов в ячейках, чтобы они все были необходимой длины.

Давайте нарисуем для опыта шахматную доску 5×5.

var rows = [];

for (var i = 0; i < 5; i++) {

var row = [];

for (var j = 0; j < 5; j++) {

if ((j + i) % 2 == 0)

row.push(new TextCell("##"));

else

row.push(new TextCell(" "));

}

rows.push(row);

}

console.log(drawTable(rows));

// → ## ## ##

// ## ##

// ## ## ##

// ## ##

// ## ## ##

Работает! Но так как у всех ячеек один размер, код форматирования таблицы не делает ничего интересного.

Исходные данные для таблицы гор, которую мы строим, содержатся в переменной MOUNTAINS, их можно скачать тут.

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

function UnderlinedCell(inner) {

this.inner = inner;

};

UnderlinedCell.prototype.minWidth = function() {

return this.inner.minWidth();

};

UnderlinedCell.prototype.minHeight = function() {

return this.inner.minHeight() + 1;

};

UnderlinedCell.prototype.draw = function(width, height) {

return this.inner.draw(width, height - 1)

.concat([repeat("-", width)]);

};

Подчёркнутая ячейка содержит другую ячейку. Она возвращает такие же размеры, как и у ячейки inner(через вызовы её методов minWidthи minHeight), но добавляет единичку к высоте из-за места, занятого чёрточками.

Рисовать её просто – мы берём содержимое ячейки innerи добавляем одну строку, заполненную чёрточками.

Теперь, имея основной движок, мы можем написать функцию, строящую сетку ячеек из нашего набора данных.

function dataTable(data) {

var keys = Object.keys(data[0]);

var headers = keys.map(function(name) {

return new UnderlinedCell(new TextCell(name));

});

var body = data.map(function(row) {

return keys.map(function(name) {

return new TextCell(String(row[name]));

});

});

return [headers].concat(body);

}

console.log(drawTable(dataTable(MOUNTAINS)));

// → name height country

// ------------ ------ -------------

// Kilimanjaro 5895 Tanzania

// … и так далее

Стандартная функция Object.keysвозвращает массив имён свойств объекта. Верхняя строка таблицы состоит из подчёркнутых ячеек с заголовками столбцов. Всё что ниже – значения из набора данных – имеет вид обычных ячеек. Мы извлекаем эти данные проходом функции mapпо массиву keys, чтобы гарантировать одинаковый порядок ячеек в каждой из строк.

Итоговая таблица напоминает таблицу из примера, только вот числа не выровнены по правому краю. Мы займёмся этим чуть позже.

Геттеры и сеттеры

При создании интерфейса можно ввести свойства, не являющиеся методами. Мы могли бы определить minHeightи minWidthкак переменные для хранения чисел. Но это потребовало бы от нас написать код вычисления их значений в конструкторе, что плохо, поскольку эти операции не связаны напрямую с конструированием объекта. Это может аукнуться, когда, например, внутренняя ячейка подчёркнутой ячейки изменяется – в этот момент размер подчеркивания тоже должен измениться.

Эти соображения привели к тому, что свойства, не являющиеся методами, многие не включают в интерфейс. Вместо прямого доступа к свойствам-значениям, используются методы типа getSomethingи setSomethingдля чтения и записи значений свойств. Но в таком подходе есть и минус – приходится писать (и читать) много дополнительных методов.

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

var pile = {

elements: ["скорлупа", "кожура", "червяк"],

get height() {

return this.elements.length;

},

set height(value) {

console.log("Игнорируем попытку задать высоту", value);

}

};

console.log(pile.height);

// → 3

pile.height = 100;

// → Игнорируем попытку задать высоту 100

В объявлении объекта записи getили setпозволяют задать функцию, которая будет вызвана при чтении или записи свойства. Можно также добавить такое свойство в существующий объект, к примеру, в prototype, используя функцию Object.defineProperty(раньше мы её уже использовали, создавая несчётные свойства).

Object.defineProperty(TextCell.prototype, "heightProp", {

get: function() { return this.text.length; }

});

var cell = new TextCell("да\nну");

console.log(cell.heightProp);

// → 2

cell.heightProp = 100;

console.log(cell.heightProp);

// → 2

Так же можно задавать свойство setв объекте, передаваемом в defineProperty, для задания метода-сеттера. Когда геттер есть, а сеттера нет, попытка записи в свойство просто игнорируется.

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

Но мы ещё не закончили с нашим упражнением по форматированию таблицы. Читать её было бы удобнее, если б числовой столбец был выровнен по правому краю. Нам нужно создать ещё один тип ячеек вроде TextCell, но чтобы текст дополнялся пробелами слева, а не справа — для выравнивания по правому краю.

Мы могли бы написать новый конструктор со всеми тремя методами в прототипе. Но прототипы могут сами иметь прототипы, и поэтому мы можем поступить умнее.

function RTextCell(text) {

TextCell.call(this, text);

}

RTextCell.prototype = Object.create(TextCell.prototype);

RTextCell.prototype.draw = function(width, height) {

var result = [];

for (var i = 0; i < height; i++) {

var line = this.text[i] || "";

result.push(repeat(" ", width - line.length) + line);

}

return result;

};

Мы повторно использовали конструктор и методы minHeightи minWidthиз обычного TextCell. И RTextCellтеперь в общем эквивалентен TextCell, за исключением того, что в методе drawнаходится другая функция.

Такая схема называется наследованием. Мы можем строить в чём-то отличные типы данных на основе существующих, не тратя много сил. Обычно новый конструктор вызывает старый (через метод call, чтобы передать ему новый объект и его значение). После этого мы можем предположить, что все поля, которые должны быть в старом объекте, добавлены. Мы наследуем прототип конструктора от старого так, что экземпляры этого типа будут иметь доступ к свойствам старого прототипа. И наконец, мы можем переопределить некоторые свойства, добавляя их к новому прототипу.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Марейн Хавербеке читать все книги автора по порядку

Марейн Хавербеке - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Выразительный JavaScript отзывы


Отзывы читателей о книге Выразительный JavaScript, автор: Марейн Хавербеке. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x