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


Авторские права

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

Здесь можно купить и скачать "Марейн Хавербеке - Выразительный JavaScript" в формате fb2, epub, txt, doc, pdf. Жанр: Программирование. Так же Вы можете читать ознакомительный отрывок из книги на сайте LibFox.Ru (ЛибФокс) или прочесть описание и ознакомиться с отзывами.
Марейн Хавербеке - Выразительный JavaScript
Рейтинг:
Название:
Выразительный JavaScript
Издательство:
неизвестно
Год:
неизвестен
ISBN:
978-1593275846
Вы автор?
Книга распространяется на условиях партнёрской программы.
Все авторские права соблюдены. Напишите нам, если Вы не согласны.

Как получить книгу?
Оплатили, но не знаете что делать дальше? Инструкция.

Описание книги "Выразительный JavaScript"

Описание и краткое содержание "Выразительный JavaScript" читать бесплатно онлайн.



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






//   ##    ##    ##

//      ##    ##

//   ##    ##    ##

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

Исходные данные для таблицы гор, которую мы строим, содержатся в переменной 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, чтобы передать ему новый объект и его значение). После этого мы можем предположить, что все поля, которые должны быть в старом объекте, добавлены. Мы наследуем прототип конструктора от старого так, что экземпляры этого типа будут иметь доступ к свойствам старого прототипа. И наконец, мы можем переопределить некоторые свойства, добавляя их к новому прототипу.

Если мы чуть отредактируем функцию dataTable, чтоб она использовала для числовых ячеек RTextCells, мы получим нужную нам таблицу.

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) {

      var value = row[name];

      // Тут поменяли:

      if (typeof value == "number")

        return new RTextCell(String(value));

      else

        return new TextCell(String(value));

    });

  });

  return [headers].concat(body);

}


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

// → … красиво отформатированная таблица

Наследование – основная часть объектно-ориентированной традиции, вместе с инкапсуляцией и полиморфизмом. Но, в то время как последние две воспринимают как отличные идеи, первая вызывает споры.

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

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

Оператор instanceof

Иногда удобно знать, произошёл ли объект от конкретного конструктора. Для этого JavaScript даёт нам бинарный оператор instanceof.

console.log(new RTextCell("A") instanceof RTextCell);

// → true

console.log(new RTextCell("A") instanceof TextCell);

// → true

console.log(new TextCell("A") instanceof RTextCell);

// → false

console.log([1] instanceof Array);

// → true

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


На Facebook В Твиттере В Instagram В Одноклассниках Мы Вконтакте
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!

Похожие книги на "Выразительный JavaScript"

Книги похожие на "Выразительный JavaScript" читать онлайн или скачать бесплатно полные версии.


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

Все книги автора Марейн Хавербеке

Марейн Хавербеке - все книги автора в одном месте на сайте онлайн библиотеки LibFox.

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

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

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

А что Вы думаете о книге? Оставьте Ваш отзыв.