8.4. Функции как данные
Самые важные особенности функций заключаются в том, что они могут определяться и вызываться. Определение и вызов функции - это синтаксические средства JavaScript и большинства других языков программирования. Однако в JavaScript функции - это не только синтаксические конструкции, но и данные, а это означает, что они могут присваиваться переменным, храниться в свойствах объектов или элементах массивов, передаваться как аргументы функциями и т. д.[13]
Чтобы понять, как функции в JavaScript могут быть одновременно синтаксическими конструкциями и данными, рассмотрим следующее определение функции:
function square(x) { return х*х; }
Это определение создает новый объект функции и присваивает его переменной square. Имя функции действительно нематериально - это просто имя переменной, которая ссылается на объект функции. Функция может быть присвоена другой переменной, и при этом работать так же, как и раньше:
var s = square; // Теперь s ссылается на ту же функцию, что и square
square(4); // => 16
s(4); // => 16
Функции могут быть также присвоены не только глобальным переменным, но и свойствам объектов. В этом случае их называют методами:
var о = {square: function(x) { return х*х; }}; // Литерал объекта
var у = о.square(16); // у = 256
Функции могут быть даже безымянными, например, в случае присваивания их элементам массива:
var а = [function(x) { return х*х; }, 20]; // Литерал объекта
а[0](а[1]); // => 400
Синтаксис вызова функции в последнем примере выглядит необычно, однако это вполне допустимый вариант применения выражения вызова!
В примере 8.2 демонстрируется, что можно делать, когда функции выступают в качестве данных. Хотя пример может показаться вам несколько сложным, комментарии объясняют, что происходит.
Пример 8.2. Использование функций как данных
// Определения нескольких простых функций
function add(x.y) { return х + у; }
function subtract(x,у) { return х - у; }
function multiply(x,у) { return х * у; }
function divide(x,y) { return x / у; }
// Эта функция принимает одну из предыдущих функций
// в качестве аргумента и вызывает ее с двумя операндами
function operate(operator, operand1, operand2) {
return operator(operand1, operand2);
}
// Так можно вызвать эту функцию для вычисления выражения (2+3)+(4*5):
var і = operate(add, operate(add, 2, 3), operate(multiply, 4, 5));
// Ради примера реализуем эти функции снова, на этот раз
// с помощью литералов функций внутри литерала объекта,
var operators = {
add: function(x,у) { return x+y; },
subtract: function(x,y) { return x-y; },
multiply: function(x,y) { return x*y; },
divide: function(x,y) { return x/y; },
pow: Math.pow // Можно использовать даже предопределенные функции
}
// Эта функция принимает имя оператора, отыскивает оператор в объекте,
// а затем вызывает его с указанными операндами.
// Обратите внимание на синтаксис вызова функции оператора,
function operate2(operation, operand1, operand2) {
if (typeof operators[operation] === "function")
return operators[operation](operand1. operand2);
else throw "неизвестный оператор":
}
// Вычислить значение ("hello" + " " + "world"):
var j = operate2("add", "hello", operate2("add", " ", "world")):
// Использовать предопределенную функцию Math.pow():
var k = operate2("pow", 10, 2):
В качестве еще одного примера использования функций как значений рассмотрим метод Array.sort(). Он сортирует элементы массива. Существует много возможных порядков сортировки (числовой, алфавитный, по датам, по возрастанию, по убыванию и т. д.), поэтому метод sort() принимает в качестве необязательного аргумента функцию, которая сообщает о том, как выполнять сортировку. Эта функция делает простую работу: получает два значения, сравнивает их и возвращает результат, указывающий, какой из элементов должен быть первым. Этот аргумент-функция делает метод Array.sort() совершенно универсальным и бесконечно гибким - он может сортировать любой тип данных в любом мыслимом порядке. Примеры использования функции Array.sort() представлены в разделе 7.8.3.
Больше книг — больше знаний!
Заберите 30% скидку новым пользователям на все книги Литрес с нашим промокодом
ПОЛУЧИТЬ СКИДКУ