arguments — это имя локального объекта в виде массива, доступного внутри каждой функции. Это странно, часто игнорируется, но является источником большого количества волшебства программирования; все основные библиотеки JavaScript используют мощь объекта arguments . С этим должен познакомиться каждый программист JavaScript.
Внутри любой функции вы можете получить к ней доступ через переменную: arguments , и она содержит массив всех аргументов, которые были переданы функции при ее вызове. На самом деле это не массив JavaScript; typeof arguments будут возвращать значение: "object" . Вы можете получить доступ к отдельным значениям аргумента через индекс массива, и он имеет свойство length как и другие массивы, но у него нет стандартных методов Array таких как push и pop .
Создать гибкие функции
Хотя это может показаться ограниченным, arguments — очень полезный объект. Например, вы можете создавать функции, которые принимают переменное число аргументов. Функция format , найденная в библиотеке base2 Дином Эдвардсом, демонстрирует эту гибкость:
function format(string) { var args = arguments; var pattern = new RegExp("%([1-" + arguments.length + "])", "g"); return String(string).replace(pattern, function(match, index) { return args[index]; }); };
Вы предоставляете строку шаблона, в которую вы добавляете заполнители для значений, используя %1 — %9 , а затем предоставляете до 9 других аргументов, которые представляют строки для вставки. Например:
format("And the %1 want to know whose %2 you %3", "papers", "shirt", "wear");
Приведенный выше код вернет строку "And the papers want to know whose shirt you wear" .
Вы могли заметить, что в определении функции для format мы указали только один аргумент: string . JavaScript позволяет нам передавать функции любое количество аргументов независимо от определения функции, а объект arguments имеет доступ ко всем из них.
Преобразовать его в реальный массив
Несмотря на то, что arguments не является реальным массивом JavaScript, мы можем легко преобразовать его в один с помощью стандартного метода Array , slice , например:
var args = Array.prototype.slice.call(arguments);
Переменная args теперь будет содержать правильный объект Array JavaScript, содержащий все значения из объекта arguments .
Создание функций с предустановленными аргументами
Объект arguments позволяет нам выполнять всевозможные трюки JavaScript. Вот определение для функции makeFunc . Эта функция позволяет вам предоставить ссылку на функцию и любое количество аргументов для этой функции. Он возвратит анонимную функцию, которая вызывает указанную вами функцию, и предоставляет предварительно заданные аргументы вместе с любыми новыми аргументами, предоставляемыми при вызове анонимной функции:
function makeFunc() { var args = Array.prototype.slice.call(arguments); var func = args.shift(); return function() { return func.apply(null, args.concat(Array.prototype.slice.call(arguments))); }; }
Первый аргумент, предоставленный makeFunc , считается ссылкой на функцию, которую вы хотите вызвать (да, в этом простом примере проверка ошибок отсутствует), и он удаляется из массива arguments. makeFunc возвращает анонимную функцию, которая использует метод apply объекта Function для вызова указанной функции.
Первый аргумент для apply относится к области, в которой будет вызываться функция; в основном к какому ключевому слову this будет относиться внутри вызываемой функции. Пока это немного продвинуто, поэтому мы просто держим это значение null . Второй аргумент — это массив значений, которые будут преобразованы в объект arguments для функции. makeFunc объединяет исходный массив значений в массив аргументов, предоставленных анонимной функции, и передает их вызываемой функции.
Допустим, вам нужно было вывести сообщение, в котором шаблон всегда был одинаковым. Чтобы избавить вас от необходимости makeFunc в кавычки шаблон каждый раз, когда вы makeFunc функцию format вы можете использовать служебную функцию makeFunc чтобы вернуть функцию, которая будет вызывать format для вас, и автоматически заполнить аргумент шаблона:
var majorTom = makeFunc(format, "This is Major Tom to ground control. I'm %1.");
Вы можете вызывать функцию majorTom несколько раз так:
majorTom("stepping through the door"); majorTom("floating in a most peculiar way");
Каждый раз, когда вы вызываете функцию majorTom она вызывает функцию format с уже заполненным первым аргументом — шаблоном. Вышеуказанные вызовы возвращают:
"This is Major Tom to ground control. I'm stepping through the door." "This is Major Tom to ground control. I'm floating in a most peculiar way."
Создайте самоссылающиеся функции
Вы можете подумать, что это круто, но подождите, у аргументов есть еще один сюрприз; у него есть еще одно полезное свойство: callee . arguments.callee содержит ссылку на функцию, которая создала объект arguments . Как мы можем использовать такую вещь? arguments.callee — удобный способ, которым анонимная функция может ссылаться на себя.
repeat- это функция, которая принимает ссылку на функцию и 2 числа. Первое число - это количество вызовов функции, а второе - задержка в миллисекундах между каждым вызовом. Вот определение дляrepeat:function repeat(fn, times, delay) { return function() { if(times-- > 0) { fn.apply(null, arguments); var args = Array.prototype.slice.call(arguments); var self = arguments.callee; setTimeout(function(){self.apply(null,args)}, delay); } }; }repeatиспользуетarguments.calleeдля получения ссылки в переменнойselfна анонимную функцию, которая запускает изначально предоставленную функцию. Таким образом, анонимная функция может вызывать себя снова после задержки, используя стандартную функциюsetTimeout.Итак, у меня есть эта, по общему признанию упрощенная, функция в моем приложении, которая берет строку и выскакивает окно с предупреждением, содержащим эту строку:
function comms(s) { alert(s); }Тем не менее, я хочу создать специальную версию этой функции, которая повторяется 3 раза с задержкой в 2 секунды между каждым разом. С моей функцией
repeatя могу сделать это:var somethingWrong = repeat(comms, 3, 2000); somethingWrong("Can you hear me, major tom?");Результатом вызова
somethingWrongявляется окно предупреждения, повторяемое 3 раза с задержкой в 2 секунды между каждым предупреждением.argumentsне часто используются, немного причудливы, но полны неожиданностей и их стоит узнать!