// Копирование начинается с элемента from_start в массиве from
// и выполняется в элементы, начиная с to_start в массиве to.
// Запомнить порядок следования аргументов такой функции довольно сложно.
function аггаусору(/* массив */ from, /* индекс */ from_start,
/* массив */ to, /* индекс */ to_start,
/* целое */ length)
{
// здесь находится реализация функции
}
// Эта версия функции чуть менее эффективная, но не требует запоминать порядок следования
// аргументов, а аргументы from_start и to_start по умолчанию принимают значение 0.
function easycopy(args) {
arraycopy(args.from,
args.from_start || 0,
// Обратите внимание, как назначаются args.to,
// значения по умолчанию
args.to_start || 0, args.length);
}
// Далее следует пример вызова функции easycopy():
var а = [1,2,3,4], b = [];
easycopy({from: a, to: b, length: 4});
8.3.4. Типы аргументов
В языке JavaScript параметры функций объявляются без указания их типов, а во время передачи значений функциям не производится никакой проверки их типов. Вы можете сделать свой программный код самодокументируемым, выбирая описательные имена для параметров функций и включая описание типов аргументов в комментарии, как это сделано в только что рассмотренном примере функции аггаусору(). Для необязательных аргументов в комментарий можно добавлять слово «необязательный» («optional»). А если функция может принимать произвольное число аргументов, можно использовать многоточие:
function max(/* число... */) { /* тело функции */ }
Как отмечалось в разделе 3.8, при необходимости JavaScript выполняет преобразование типов. Таким образом, если определить функцию, которая ожидает получить строковый аргумент, а затем вызвать ее с аргументом какого-нибудь другого типа, значение аргумента просто будет преобразовано в строку, когда функция пытается обратиться к нему как к строке. В строку может быть преобразовано любое простое значение, и все объекты имеют методы toString() (правда, не всегда полезные); тем самым устраняется вероятность появления ошибки.
Однако такой подход может использоваться не всегда. Вернемся к методу аггаусору(), продемонстрированному выше. Он ожидает получить массив в первом аргументе. Любое обращение к функции окажется неудачным, если первым аргументом будет не массив (или, возможно, объект, подобный массиву). Если функция должна вызываться чаще, чем один-два раза, следует добавить в нее проверку соответствия типов аргументов. Гораздо лучше сразу же прервать вызов функции в случае передачи аргументов ошибочных типов, чем продолжать выполнение, которое потерпит неудачу с сообщением об ошибке, запутывающим ситуацию. Ниже приводится пример функции, выполняющей проверку типов. Обратите внимание, что она использует функцию isArrayLike() из раздела 7.11:
// Возвращает сумму элементов массива (или объекта, подобного массиву) а.
// Все элементы массива должны быть числовыми, при этом значения null
// и undefined игнорируются,
function sum(a) {
if (isArrayLike(a)) {
var total = 0;
for(var і = 0; і < a.length; і++) { // Цикл по всем элементам
var element = a[і];
if (element == null) continue; // Пропустить null и undefined
if (isFinite(element))
total += element;
else throw new Error("sum(): все элементы должны быть числами");
}
return total;
}
else throw new Error("sum(): аргумент должен быть массивом");
}
Этот метод sum() весьма строго относится к проверке типов входных аргументов и генерирует исключения с достаточно информативными сообщениями, если типы входных аргументов не соответствуют ожидаемым. Тем не менее он остается достаточно гибким, обслуживая наряду с настоящими массивами объекты, подобные массивам, и игнорируя элементы, имеющие значения null и undefined.