Вход/Регистрация
JavaScript. Подробное руководство, 6-е издание
вернуться

Флэнаган Дэвид

Шрифт:

// аргументы f имеют отличающиеся строковые представления,

function memoize(f) {

var cache = {}; // Кэш значений сохраняется в замыкании,

return function {

// Создать строковую версию массива arguments для использования

// в качестве ключа кэша.

var key = arguments.length + Array.prototype.join.call(arguments,",")

if (key in cache) return cache[key];

else return cache[key] = f.apply(this, arguments);

};

}

Функция

memoize
создает новый объект для использования в качестве кэша и присваивает его локальной переменной, благодаря чему он остается доступным (через замыкание) только для возвращаемой функции. Возвращаемая функция преобразует свой массив
arguments
в строку и использует ее как имя свойства объекта-кэша. Если значение присутствует в кэше, оно просто возвращается в качестве результата. В противном случае вызывается оригинальная функция, вычисляющая значение для заданной комбинации значений аргументов; полученное значение помещается в кэш и возвращается. Следующий фрагмент демонстрирует, как можно использовать функцию
memoize:

// Возвращает наибольший общий делитель двух целых чисел, используя

// алгоритм Эвклида: http://en.wikipedia.org/wiki/Euclidean_algorithm

function gcd(a.b) { // Проверка типов а и b опущена

var t; // Временная переменная для обмена

if (а < b) t=b, b=a, a=t; // Убедиться, что а >= b

while(b ! = 0) t=b, b = a%b, a=t; // Это алгоритм Эвклида поиска НОД

return а;

}

var gcdmemo = memoize(gcd);

gcdmemo(85, 187) // => 17

// Обратите внимание, что при мемоизации рекурсивных функций желательно,

// чтобы рекурсия выполнялась в мемоизованной версии, а не в оригинале,

var factorial = memoize(function(n) {

return (n <= 1) ? 1 : n * factorial(n-1);

});

factorial(5) // => 120. Также поместит в кэш факториалы для чисел 4, 3, 2 и 1.

9

Классы и модули

Введение в JavaScript-объекты было дано в главе 6, где каждый объект трактовался как уникальный набор свойств, отличающих его от любых других объектов. Однако часто бывает полезнее определить класс объектов, обладающих общими свойствами. Члены, или экземпляры, класса обладают собственными свойствами, определяющими их состояние, но они также обладают свойствами (обычно методами), определяющими их поведение. Эти особенности поведения определяются классом и являются общими для всех экземпляров. Например, можно объявить класс

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

Классы в языке JavaScript основаны на использовании механизма наследования прототипов. Если два объекта наследуют свойства от одного и того же объекта-прототипа, говорят, что они принадлежат одному классу. С прототипами и наследованием мы познакомились в разделах 6.1.3 и 6.2.2. Сведения из этих разделов вам обязательно потребуются для понимания того, о чем рассказывается в этой главе. В этой главе прототипы будут рассматриваться в разделе 9.1.

Если два объекта наследуют один и тот же прототип, обычно (но не обязательно) это означает, что они были созданы и инициализированы с помощью одного конструктора. С конструкторами мы познакомились в разделах 4.6, 6.1.2 и 8.2.3. Дополнительные сведения о них в этой главе приводятся в разделе 9.2.

Те, кто знаком со строго типизированными объектно-ориентированными языками программирования, такими как Java или C++, могут заметить, что классы в языке JavaScript совершенно не похожи на классы в этих языках. Конечно, есть некоторые синтаксические сходства, и имеется возможность имитировать многие особенности «классических» классов в JavaScript. Но лучше будет с самого начала понять, что классы и механизм наследования на основе прототипов в языке JavaScript существенно отличаются от классов и механизма наследования на основе классов в языке Java и подобных ему. В разделе 9.3 демонстрируются приемы имитации классических классов на языке JavaScript.

Еще одной важной особенностью классов в языке JavaScript является возможность динамического расширения. Эта особенность описывается в разделе 9.4. Классы можно также интерпретировать как типы данных, и в разделе 9.5 будет представлено несколько способов определения класса объекта. В этом разделе вы также познакомитесь с философией программирования, известной как «утиная типизация» («duck-typing»), которая во главу угла ставит не тип объекта, а его возможности.

После знакомства со всеми этими основами объектно-ориентированного программирования в JavaScript мы перейдем в этой же главе к изучению более практического материала. В разделе 9.6 будут представлены два примера непростых классов и продемонстрировано несколько практических объектно-ориентированных приемов расширения этих классов. В разделе 9.7 будет показано (на множестве примеров), как расширять или наследовать другие классы и как создавать иерархии классов в языке JavaScript. В разделе 9.8 рассматриваются дополнительные приемы работы с классами с использованием новых возможностей, появившихся в ECMAScript 5.

  • Читать дальше
  • 1
  • ...
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: