Дэвид Флэнаган - JavaScript. Подробное руководство, 6-е издание
- Название:JavaScript. Подробное руководство, 6-е издание
- Автор:
- Жанр:
- Издательство:Символ-Плюс
- Год:2012
- Город:СПб
- ISBN:978-5-93286-215-5
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дэвид Флэнаган - JavaScript. Подробное руководство, 6-е издание краткое содержание
Эта книга - одновременно и руководство программиста, и полноценный справочник по базовому языку JavaScript и клиентским прикладным интерфейсам, предоставляемым веб-броузерами.
JavaScript. Подробное руководство, 6-е издание - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
var mean = total/data.length; // Среднее значение равно З
// Чтобы найти стандартное отклонение, необходимо вычислить сумму квадратов
// отклонений элементов от среднего,
total = 0;
for(var і = 0; і < data.length; i++) {
var deviation = data[i] - mean;
total += deviation * deviation;
}
var stddev = Math.sqrt(total/(data.length-1)); // Стандартное отклонение = 2
Те же вычисления можно выполнить в более кратком функциональном стиле, задействовав методы массивов mар()
и reduce(),
как показано ниже (краткое описание этих методов приводится в разделе 7.9):
// Для начала необходимо определить две простые функции
var sum = function(x,у) { return х+у; };
var square = function(x) { return x*x; };
// Затем использовать их совместно с методами класса Array для вычисления
// среднего и стандартного отклонения
var data = [1,1,3,5,5];
var mean = data.reduce(sum)/data.length;
var deviations = data.map(function(x) {return x-mean;});
var stddev = Math.sqrt(deviations.map(square).reduce(sum)/(data.length-1));
A как быть, если в нашем распоряжении имеется только реализация ЕСМА-Script 3, где отсутствуют эти новейшие методы массивов? Можно определить собственные функции mар() и reduce(), которые будут использовать встроенные методы при их наличии:
// Вызывает функцию f для каждого элемента массива и возвращает массив результатов.
// Использует метод Array.prototype.mар, если он определен,
var mар = Array.prototype.тар
? function(a, f) { return a.map(f); } // Если метод map() доступен
: function(a,f) { // Иначе реализовать свою версию
var results = [];
for(var і = 0, len = a.length; і < len; і++) {
if (і in a) results[i] = f.call(null, a[i], і, a);
}
return results;
};
// Выполняет свертку массива в единственное значение, используя функцию f
// и необязательное начальное значение. Использует метод Array.prototype.reduce,
// если он определен.
var reduce = Array.prototype.reduce
? function(a, f, initial) { // Если метод reduce() доступен,
if (arguments.length > 2)
return a.reduce(f, initial); // Если указано начальное значение,
else return a.reduce(f); // Иначе без начального значения.
}
: function(a, f, initial) { // Этот алгоритм взят из спецификации ES5
var і = 0, len = a.length, accumulator;
// Использовать указанное начальное значение или первый элемент а
if (arguments.length > 2)
accumulator = initial;
else { // Найти первый элемент массива с определенным значением
if (len == 0) throw TypeError();
while(i < len) {
if (i in a) {
accumulator = a[i++];
break;
}
else i++;
}
if (i == len) throw TypeError();
}
// Теперь вызвать f для каждого оставшегося элемента массива
while(i < len) {
if (і in а)
accumulator = f.call(undefined, accumulator, a[i], i, a);
i++;
}
return accumulator;
};
После определения этих функций map()
и reduce()
вычисление среднего и стандартного отклонения будет выглядеть так:
var data = [1,1,3,5,5];
var sum = function(x.y) { return x+y; };
var square = function(x) { return x*x; };
var mean = reduce(data, sum)/data.length;
var deviations = map(data, function(x) {return x-mean;});
var stddev = Math.sqrt(reduce(map(deviations, square), sum)/(data.length-1));
8.8.2. Функции высшего порядка
Функции высшего порядка - это функции, которые оперируют функциями, принимая одну или более функций и возвращая новую функцию. Например:
// Эта функция высшего порядка возвращает новую функцию, которая передает свои аргументы
// функции f и возвращает логическое отрицание значения, возвращаемого функцией f;
function not(f) {
return function() { // Возвращает новую функцию
var result = f.apply(this, arguments); // вызов f
return !result; // и инверсия результата.
};
}
var even = function(x) { // Функция, определяющая четность числа
return х % 2 === 0;
};
var odd = not(even); // Новая функция, выполняющая противоположную операцию
[1,1,3,5,5].every(odd); // => true: все элементы массива нечетные
Функция not()
в примере выше является функцией высшего порядка, потому что она принимает функцию в виде аргумента и возвращает новую функцию. В качестве еще одного примера рассмотрим функцию mаррег(),
представленную ниже. Она принимает функцию в виде аргумента и возвращает новую функцию, которая отображает один массив в другой, применяя указанную функцию. Данная функция использует функцию mар(),
которая была определена выше, и важно понимать, чем отличаются эти две функции:
// Возвращает функцию, которая принимает массив в виде аргумента, применяет функцию f
// к каждому элементу и возвращает массив возвращаемых значений.
// Эта функция отличается от функции тар(), представленной выше,
function mapper(f) {
return function(a) { return map(a, f); };
}
var increment = function(x) { return x+1; };
var incrementer = mapper(increment);
incrementer([1,2,3]) // => [2,3,4]
Ниже приводится пример еще одной, более универсальной функции, которая принимает две функции, f и g, и возвращает новую функцию, которая возвращает результат f(g()):
// Возвращает новую функцию, которая вычисляет f(g(...)). Возвращаемая функция h
// передает все свои аргументы функции g, затем передает значение, полученное от g,
// функции f и возвращает результат вызова f. Обе функции, f и g,
// вызываются с тем же значением this, что и h.
function compose(f,g) {
return function() {
// Для вызова f используется call, потому что ей передается
// единственное значение, а для вызова g используется apply,
// потому что ей передается массив значений,
return f.call(this, g.apply(this, arguments));
};
Интервал:
Закладка: