Какое свойство функции возвращает массив аргументов
Перейти к содержимому

Какое свойство функции возвращает массив аргументов

Псевдомассив аргументов «arguments»

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

В JavaScript любая функция может быть вызвана с произвольным количеством аргументов.

function go(a,b) < alert("a="+a+", b="+b); >go(1); // a=1, b=undefined go(1,2); // a=1, b=2 go(1,2,3); // a=1, b=2, третий аргумент не вызовет ошибку

В JavaScript нет «перегрузки» функций

В некоторых языках программист может создать две функции с одинаковым именем, но разным набором аргументов, а при вызове интерпретатор сам выберет нужную:

function log(a) < . >function log(a, b, c) < . >log(a); // вызовется первая функция log(a, b, c); // вызовется вторая функция

Это называется «полиморфизмом функций» или «перегрузкой функций». В JavaScript ничего подобного нет.

Может быть только одна функция с именем log , которая вызывается с любыми аргументами.

А уже внутри она может посмотреть, с чем вызвана и по-разному отработать.

В примере выше второе объявление log просто переопределит первое.

Доступ к «лишним» аргументам

Как получить значения аргументов, которых нет в списке параметров?

Доступ к ним осуществляется через «псевдо-массив» arguments.

Он содержит список аргументов по номерам: arguments[0] , arguments[1] …, а также свойство length .

Например, выведем список всех аргументов:

function sayHi() < for (var i = 0; i < arguments.length; i++) < alert( "Привет, " + arguments[i] ); >> sayHi("Винни", "Пятачок"); // 'Привет, Винни', 'Привет, Пятачок'

Все параметры находятся в arguments , даже если они есть в списке. Код выше сработал бы также, будь функция объявлена sayHi(a,b,c) .

Связь между arguments и параметрами

В старом стандарте JavaScript псевдо-массив arguments и переменные-параметры ссылаются на одни и те же значения.

В результате изменения arguments влияют на параметры и наоборот.

function f(x) < arguments[0] = 5; // меняет переменную x alert( x ); // 5 >f(1);
function f(x) < x = 5; alert( arguments[0] ); // 5, обновлённый x >f(1);

В современной редакции стандарта это поведение изменено. Аргументы отделены от локальных переменных:

function f(x) < "use strict"; // для браузеров с поддержкой строгого режима arguments[0] = 5; alert( x ); // не 5, а 1! Переменная "отвязана" от arguments >f(1);

Если вы не используете строгий режим, то чтобы переменные не менялись «неожиданно», рекомендуется никогда не изменять arguments .

arguments – это не массив

Частая ошибка новичков – попытка применить методы Array к arguments . Это невозможно:

function sayHi() < var a = arguments.shift(); // ошибка! нет такого метода! >sayHi(1);

Дело в том, что arguments – это не массив Array .

В действительности, это обычный объект, просто ключи числовые и есть length . На этом сходство заканчивается. Никаких особых методов у него нет, и методы массивов он тоже не поддерживает.

Впрочем, никто не мешает сделать обычный массив из arguments , например так:

var args = []; for (var i = 0; i

Такие объекты иногда называют «коллекциями» или «псевдомассивами».

Пример: копирование свойств copy(dst, src1, src2. )

Иногда встаёт задача – скопировать в существующий объект свойства из одного или нескольких других.

Напишем для этого функцию copy . Она будет работать с любым числом аргументов, благодаря использованию arguments .

copy(dst, src1, src2…) Копирует свойства из объектов src1, src2. в объект dst . Возвращает получившийся объект.

    Для объединения нескольких объектов в один:

var vasya = < age: 21, name: 'Вася', surname: 'Петров' >; var user = < isAdmin: false, isEmailConfirmed: true >; var student = < university: 'My university' >; // добавить к vasya свойства из user и student copy(vasya, user, student); alert( vasya.isAdmin ); // false alert( vasya.university ); // My university
// скопирует все свойства в пустой объект var userClone = copy(<>, user);

А вот и реализация:

function copy() < var dst = arguments[0]; for (var i = 1; i < arguments.length; i++) < var arg = arguments[i]; for (var key in arg) < dst[key] = arg[key]; >> return dst; >

Здесь первый аргумент copy – это объект, в который нужно копировать, он назван dst . Для упрощения доступа к нему можно указать его прямо в объявлении функции:

function copy(dst) < // остальные аргументы остаются безымянными for (var i = 1; i < arguments.length; i++) < var arg = arguments[i]; for (var key in arg) < dst[key] = arg[key]; >> return dst; >

Аргументы по умолчанию через ||

Если функция вызвана с меньшим количеством аргументов, чем указано, то отсутствующие аргументы считаются равными undefined .

Зачастую в случае отсутствия аргумента мы хотим присвоить ему некоторое «стандартное» значение или, иначе говоря, значение «по умолчанию». Это можно удобно сделать при помощи оператора логическое ИЛИ || .

Например, функция showWarning , описанная ниже, должна показывать предупреждение. Для этого она принимает ширину width , высоту height , заголовок title и содержимое contents , но большая часть этих аргументов необязательна:

function showWarning(width, height, title, contents) < width = width || 200; // если не указана width, то width = 200 height = height || 100; // если нет height, то height = 100 title = title || "Предупреждение"; //. >

Это отлично работает в тех ситуациях, когда «нормальное» значение параметра в логическом контексте отлично от false . В коде выше, при передаче width = 0 или width = null , оператор ИЛИ заменит его на значение по умолчанию.

А что, если мы хотим использовать значение по умолчанию только если width === undefined ? В этом случае оператор ИЛИ уже не подойдёт, нужно поставить явную проверку:

function showWarning(width, height, title, contents) < if (width === undefined) width = 200; if (height === undefined) height = 100; if (title === undefined) title = "Предупреждение"; //. >

Устаревшее свойство arguments.callee

Используйте NFE вместо arguments.callee

Это свойство устарело, при use strict оно не работает.

Единственная причина, по которой оно тут – это то, что его можно встретить в старом коде, поэтому о нём желательно знать.

Современная спецификация рекомендует использовать именованные функциональные выражения (NFE).

В старом стандарте JavaScript объект arguments не только хранил список аргументов, но и содержал в свойстве arguments.callee ссылку на функцию, которая выполняется в данный момент.

function f() < alert( arguments.callee === f ); // true >f();

Эти два примера будут работать одинаково:

// подвызов через NFE var factorial = function f(n) < return n==1 ? 1 : n*f(n-1); >; // подвызов через arguments.callee var factorial = function(n) < return n==1 ? 1 : n*arguments.callee(n-1); >;

В учебнике мы его использовать не будем, оно приведено для общего ознакомления.

arguments.callee.caller

Устаревшее свойство arguments.callee.caller хранит ссылку на функцию, которая вызвала данную.

Это свойство тоже устарело

Это свойство было в старом стандарте, при use strict оно не работает, как и arguments.callee .

Также ранее существовало более короткое свойство arguments.caller . Но это уже раритет, оно даже не кросс-браузерное. А вот свойство arguments.callee.caller поддерживается везде, если не использован use strict , поэтому в старом коде оно встречается.

f1(); function f1() < alert( arguments.callee.caller ); // null, меня вызвали из глобального кода f2(); >function f2() < alert( arguments.callee.caller ); // f1, функция, из которой меня вызвали f3(); >function f3() < alert( arguments.callee.caller ); // f2, функция, из которой меня вызвали >

В учебнике мы это свойство также не будем использовать.

«Именованные аргументы»

Именованные аргументы – альтернативная техника работы с аргументами, которая вообще не использует arguments .

Некоторые языки программирования позволяют передать параметры как-то так: f(width=100, height=200) , то есть по именам, а что не передано, тех аргументов нет. Это очень удобно в тех случаях, когда аргументов много, сложно запомнить их порядок и большинство вообще не надо передавать, по умолчанию подойдёт.

Такая ситуация часто встречается в компонентах интерфейса. Например, у «меню» может быть масса настроек отображения, которые можно «подкрутить» но обычно нужно передать всего один-два главных параметра, а остальные возьмутся по умолчанию.

В JavaScript для этих целей используется передача аргументов в виде объекта, а в его свойствах мы передаём параметры.

function showWarning(options) < var width = options.width || 200; // по умолчанию var height = options.height || 100; var contents = options.contents || "Предупреждение"; // . >

Вызвать такую функцию очень легко. Достаточно передать объект аргументов, указав в нем только нужные:

showWarning(< contents: "Вы вызвали функцию" // и всё понятно! >);

Сравним это с передачей аргументов через список:

showWarning(null, null, "Предупреждение!"); // мысль программиста "а что это за null, null в начале? ох, надо глядеть описание функции"

Не правда ли, объект – гораздо проще и понятнее?

Ещё один бонус кроме красивой записи – возможность повторного использования объекта аргументов:

var opts = < width: 400, height: 200, contents: "Текст" >; showWarning(opts); opts.contents = "Другой текст"; showWarning(opts); // вызвать с новым текстом, без копирования других аргументов

Именованные аргументы применяются во многих JavaScript-фреймворках.

Итого

  • Полный список аргументов, с которыми вызвана функция, доступен через arguments .
  • Это псевдомассив, то есть объект, который похож на массив, в нём есть нумерованные свойства и length , но методов массива у него нет.
  • В старом стандарте было свойство arguments.callee со ссылкой на текущую функцию, а также свойство arguments.callee.caller , содержащее ссылку на функцию, которая вызвала данную. Эти свойства устарели, при use strict обращение к ним приведёт к ошибке.
  • Для указания аргументов по умолчанию, в тех случаях, когда они заведомо не false , удобен оператор || .

В тех случаях, когда возможных аргументов много и, в особенности, когда большинство их имеют значения по умолчанию, вместо работы с arguments организуют передачу данных через объект, который как правило называют options .

Возможен и гибридный подход, при котором первый аргумент обязателен, а второй – options , который содержит всевозможные дополнительные параметры:

function showMessage(text, options) < // показать сообщение text, настройки показа указаны в options >

Объект arguments

Объект arguments — это подобный массиву объект, который содержит аргументы, переданные в функцию.

Примечание: Если вы пишете ES6-совместимый код, то лучше использовать остаточные параметры.

Примечание: «Подобный массиву» означает, что arguments имеет свойство length , а элементы индексируются начиная с нуля. Но при этом он не может обращаться к встроенным методам Array , таким как forEach() или map() . Подробнее об этом в §Описании.

Интерактивный пример

Синтаксис

arguments

Описание

Объект arguments — это локальная переменная, доступная внутри любой (нестрелочной) функции. Объект arguments позволяет ссылаться на аргументы функции внутри неё. Он состоит из переданных в функцию аргументов, индексация начинается с 0. Например, если в функцию было передано 3 аргумента, обратиться к ним можно следующим образом:

[0]; arguments[1]; arguments[2]; 

Аргументам может быть присвоено значение:

[1] = "new value"; 

Объект arguments не является Array . Он похож на массив, но не обладает ни одним из его свойств, кроме length . Например, у него нет метода pop . Однако, он может быть преобразован в обычный массив:

var args = Array.prototype.slice.call(arguments); var args = [].slice.call(arguments); // ES2015 const args = Array.from(arguments); const args = [. arguments]; 

Предупреждение: Использование slice на объекте arguments не позволяет сделать оптимизации в некоторых JavaScript движках (например, V8 — подробнее). Если они важны, можно попробовать вместо этого создать новый массив с аналогичной длиной и заполнить его элементами объекта arguments. Альтернативный вариант — использовать конструктор Array как функцию:

var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments); 

Объект arguments можно использовать при вызове функции с бо́льшим количеством аргументов, чем было предусмотрено в её объявлении. Такой способ удобен для функций, в которые допустимо передавать переменное количество аргументов. Можно воспользоваться arguments.length , чтобы определить количество переданных в функцию аргументов, а затем обработать каждый из них с помощью объекта arguments . Чтобы определить количество параметров функции, описанных в её сигнатуре (en-US) , можно использовать свойство Function.length .

Использование typeof с объектом arguments

Применение оператора typeof к arguments вернёт ‘object’.

console.log(typeof arguments); // 'object'

Определение типов аргументов может быть выполнено применением оператора typeof и индексацией.

// выведет тип первого аргумента console.log(typeof arguments[0]);

Использование оператора расширения для объекта arguments

Как и с обычными массива-подобными объектами, для преобразования объекта arguments в обычный массив можно использовать метод Array.from() или оператор расширения:

var args = Array.from(arguments); var args = [. arguments]; 

Свойства

Ссылка на функцию, которая выполняется в текущий момент.

Ссылка на функцию, которая вызвала функцию, выполняющуюся в текущий момент.

Количество переданных в функцию аргументов.

Возвращает новый объект Array Iterator , содержащий значения для каждого индекса в массиве.

Примеры

Создание функции, соединяющей несколько строк

Данный пример описывает функцию, которая соединяет несколько строк. Для этой функции объявлен только один аргумент, определяющий символ-разделитель соединяемых элементов. Функция определена следующим образом:

function myConcat(separator)  var args = Array.prototype.slice.call(arguments, 1); return args.join(separator); > 

Вы можете передать любое количество аргументов в эту функцию. Она создаёт строку, используя каждый аргумент:

// возвращает "red, orange, blue" myConcat(", ", "red", "orange", "blue"); // получает "elephant; giraffe; lion; cheetah" myConcat("; ", "elephant", "giraffe", "lion", "cheetah"); // выводит "sage. basil. oregano. pepper. parsley" myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley"); 

Функция, создающая HTML списки

В данном примере приведена функция, которая создаёт строку с HTML-разметкой для списка. Единственный её аргумент — строка, определяющая вид списка: если его значение равно «u», формируется неупорядоченный (маркированный) список, а если «o» — то упорядоченный (нумерованный):

Вы можете использовать любое количество аргументов, а функция добавит каждый элемент в список заданного первым аргументом типа. Например:

Остаточные, деструктурированные и параметры по умолчанию

function foo(. args)  return arguments; > foo(1, 2, 3); // 

Тем не менее, в нестрогих функциях соответствие между их аргументами и объектом arguments существует только в том случае, если функция не содержит никаких остаточных параметров, параметров по умолчанию или деструктурированных параметров. Например, в функции, приведённой ниже, используется параметр по умолчанию, и в данном случае возвращаемый результат будет равен 10, а не 100:

function bar(a = 1)  arguments[0] = 100; return a; > bar(10); // 10 
function zoo(a)  arguments[0] = 100; return a; > zoo(10); // 100 

На самом деле, если остаточные параметры, параметры по умолчанию или деструктурированные параметры не используются, формальные аргументы будут ссылаться на последние значения объекта arguments , при считывании значений формальных аргументов будут считаны последние данные из arguments , а при изменении значений формальных аргументов будет обновлён и объект arguments . Пример приведён в коде ниже:

function func(a, b)  arguments[0] = 90; arguments[1] = 99; console.log(a + " " + b); > func(1, 2); //90, 99 
function func(a, b)  a = 9; b = 99; console.log(arguments[0] + " " + arguments[1]); > func(3, 4); //9, 99 

Но в случае, когда применяются остаточные параметры, параметры по умолчанию или деструктурированные параметры, будет обработано нормальное поведение, как в случае параметров по умолчанию:

function func(a, b, c = 9)  arguments[0] = 99; arguments[1] = 98; console.log(a + " " + b); > func(3, 4); //3, 4 

Спецификации

Specification
ECMAScript Language Specification
# sec-arguments-exotic-objects

Поддержка браузерами

BCD tables only load in the browser

Смотрите также

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 7 авг. 2023 г. by MDN contributors.

Your blueprint for a better internet.

MDN

Support

  • Product help
  • Report an issue

Our communities

Developers

  • Web Technologies
  • Learn Web Development
  • MDN Plus
  • Hacks Blog
  • Website Privacy Notice
  • Cookies
  • Legal
  • Community Participation Guidelines

Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.

Объект arguments

Устаревший способ получить все значения, переданные в функцию при вызове.

Время чтения: меньше 5 мин

Открыть/закрыть навигацию по статье

Обновлено 6 февраля 2023

Кратко

Скопировать ссылку «Кратко» Скопировано

Устаревший способ получить все значения, переданные в функцию при вызове в виде массивоподобного объекта. Используется в функциях, которые принимают произвольное количество аргументов.

Не работает в стрелочных функциях.

Используйте синтаксис остаточных (rest) параметров, он современнее и лучше читается.

Используйте arguments только если пишете код в версии языка раньше ES6, выпущенной в 2015 году.

Пример

Скопировать ссылку «Пример» Скопировано

Функция, которая принимает произвольное количество аргументов, выбирает из них только строки и склеивает с помощью пробела:

 function joinStrings()  const strings = [] for (let i = 0; i < arguments.length; i++)  if (typeof arguments[i] === 'string')  strings.push(arguments[i]) > > return strings.join(' ')> const result = joinStrings('hello', 12, 'world', false, null)console.log(result)// hello world function joinStrings()  const strings = [] for (let i = 0; i  arguments.length; i++)  if (typeof arguments[i] === 'string')  strings.push(arguments[i]) > > return strings.join(' ') > const result = joinStrings('hello', 12, 'world', false, null) console.log(result) // hello world      

Как понять

Скопировать ссылку «Как понять» Скопировано

arguments доступно во всех видах функций, за исключением стрелочных.

arguments — массивоподобный объект, к его элементам можно обращаться по индексу, у него есть свойство length , но arguments не имеет остальных методов массива, таких как push ( ) или filter ( ) .

Массивоподобность объекта позволяет обойти его элементы с помощью цикла.

На практике

Скопировать ссылку «На практике» Скопировано

Андрей Паскаль советует

Скопировать ссылку «Андрей Паскаль советует» Скопировано

�� Иногда нужно создать функцию-обработчик для существующего события. Но при этом вам могут быть нужны не все лидирующие параметры. Например, из трёх параметров вам нужны только второй и третий. Что бы не получать назойливые предупреждения от линтера о неиспользованном первом параметре, можно использовать синтаксис остаточных параметров плюс деструктурирование массива:

 function myHandler(. [, second, third])  console.log(`Второй параметр = $`) console.log(`Третий параметр = $`)> myHandler(1, 2, 3) // Второй параметр = 2// Третий параметр = 3 function myHandler(. [, second, third])  console.log(`Второй параметр = $second>`) console.log(`Третий параметр = $third>`) > myHandler(1, 2, 3) // Второй параметр = 2 // Третий параметр = 3      

+ Развернуть

Николай Лопин советует

Скопировать ссылку «Николай Лопин советует» Скопировано

��️ В новом коде лучше применять синтаксис остаточных параметров. В этом случае у нас появляется настоящий массив переданных аргументов. Вот как будет выглядеть пример из начала статьи в этом синтаксисе:

 function joinStrings(. rest)  return rest .filter(function (value)  return typeof value === 'string' >) .join(' ')> const result = joinStrings('hello', 12, 'world', false, null)console.log(result)// hello world function joinStrings(. rest)  return rest .filter(function (value)  return typeof value === 'string' >) .join(' ') > const result = joinStrings('hello', 12, 'world', false, null) console.log(result) // hello world      

Напишите функцию, фильтрующую массив объектов по значению свойства JS

Я учусь JS. Короче в одном из скаченных курсов есть задания. И вот там такое задание: Цель задания Попрактиковаться в использовании сложных структур данных (массив объектов) и работе со свойствами. Задание Напишите функцию, фильтрующую массив объектов по значению свойства. Массив, название свойства и нужное значение должны передаваться в качестве аргументов. Пример использования:

let objects = [ < name: 'Василий', surname: 'Васильев' >, < name: 'Иван', surname: 'Иванов' >, < name: 'Пётр', surname: 'Петров' >] // fn - функция, которую нужно написать (хорошее название тоже нужно придумать) let result = fn(objects, 'name', 'Иван'); 

/* Результат выполнения должен быть:

*/ В конце файла с кодом домашнего задания напишите конструкцию export default <название функции>, чтобы была возможность автоматической проверки получившейся функции. Рекомендации к выполнению Не забывайте о том, что массивы и объекты передаются по ссылке. Поэтому для формирования массива-результата нужно создать новый отдельный массив, а не изменять старый, который пришёл в качестве параметра.

let objects = [ < name: 'Василий', surname: 'Васильев' >, < name: 'Иван', surname: 'Иванов' >, < name: 'Пётр', surname: 'Петров' >] function filterObjValues(objects, key, value) < //функция с 3мя атрибутами for (i=1; i :$ $:$`; //переменная = name:Иван surname:Иванов. console.log(result); //выводим это в консоль. > > > filterObjValues(objects, 'name', 'Иван'); //запускаем функцию 

Если можно подскажите куда я не правильно завернул? ничего не работает =) Пока прошел (функции, циклы, деструктаризацию, условия, массивы и объекты), поэтому задание рассчитано максимум на это. Сердешко вам

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *