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

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

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

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

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

The source for this interactive example is stored in a GitHub repository. If you’d like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

Синтаксис

arguments

Описание

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

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

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

arguments[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. Чтобы определить количество параметров функции, описанных в её сигнатуре, можно использовать свойство 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];

Свойства

arguments.callee
Ссылка на функцию, которая выполняется в текущий момент.
arguments.caller
Ссылка на функцию, которая вызвала функцию, выполняющуюся в текущий момент.
arguments.length
Количество переданных в функцию аргументов.
arguments[@@iterator]
Возвращает новый объект 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 list(type) {
var result = “<” + type + “l><li>”;
var args = Array.prototype.slice.call(arguments, 1);
result += args.join(“</li><li>”);
result += “</li></” + type + “l>”; // конец списка

return result;
}

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

var listHTML = list(“u”, “One”, “Two”, “Three”);

/* listHTML:

“<ul><li>One</li><li>Two</li><li>Three</li></ul>”

*/

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

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

function foo(…args) {
return arguments;
}
foo(1, 2, 3);

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

function bar(a=1) {
arguments[0] = 100;
return a;
}
bar(10);

В следующем примере возвращается 100, поскольку здесь нет оставшихся параметров, параметров по умолчанию или деструктурированных параметров:

function zoo(a) {
arguments[0] = 100;
return a;
}
zoo(10);

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

function func(a, b) {
arguments[0] = 90;
arguments[1] = 99;
console.log(a + ” ” + b);
}

func(1, 2);

или

function func(a, b) {
a = 9;
b = 99;
console.log(arguments[0] + ” ” + arguments[1]);
}

func(3, 4);

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

function func(a, b, c=9) {
arguments[0] = 99;
arguments[1] = 98;
console.log(a + ” ” + b);
}

func(3, 4);

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

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

The compatibility table on this page is generated from structured data. If you’d like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

КомпьютерыМобильныеServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome для AndroidFirefox для AndroidOpera для AndroidSafari on iOSSamsung InternetNode.js
argumentsChrome
Полная поддержка

1

Edge
Полная поддержка

12

Firefox
Полная поддержка

1

IE
Полная поддержка

3

Opera
Полная поддержка

3

Safari
Полная поддержка

1

WebView Android
Полная поддержка

1

Chrome Android
Полная поддержка

18

Firefox Android
Полная поддержка

4

Opera Android
Полная поддержка

10.1

Safari iOS
Полная поддержка

1

Samsung Internet Android
Полная поддержка

1.0

nodejs
Полная поддержка

Да

calleeChrome
Полная поддержка

1

Edge
Полная поддержка

12

Firefox
Полная поддержка

1

IE
Полная поддержка

6

Opera
Полная поддержка

4

Safari
Полная поддержка

1

WebView Android
Полная поддержка

1

Chrome Android
Полная поддержка

18

Firefox Android
Полная поддержка

4

Opera Android
Полная поддержка

10.1

Safari iOS
Полная поддержка

1

Samsung Internet Android
Полная поддержка

1.0

nodejs
Полная поддержка

Да

lengthChrome
Полная поддержка

1

Edge
Полная поддержка

12

Firefox
Полная поддержка

1

IE
Полная поддержка

4

Opera
Полная поддержка

4

Safari
Полная поддержка

1

WebView Android
Полная поддержка

1

Chrome Android
Полная поддержка

18

Firefox Android
Полная поддержка

4

Opera Android
Полная поддержка

10.1

Safari iOS
Полная поддержка

1

Samsung Internet Android
Полная поддержка

1.0

nodejs
Полная поддержка

Да

@@iteratorChrome
Полная поддержка

52

Edge
Полная поддержка

12

Firefox
Полная поддержка

46

IE
Нет поддержки

Нет

Opera
Полная поддержка

39

Safari
Полная поддержка

9

WebView Android
Полная поддержка

52

Chrome Android
Полная поддержка

52

Firefox Android
Полная поддержка

46

Opera Android
Полная поддержка

41

Safari iOS
Полная поддержка

9

Samsung Internet Android
Полная поддержка

6.0

nodejs
Полная поддержка

Да

Легенда

Полная поддержка
 
Полная поддержка

Нет поддержки
 
Нет поддержки

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

  • Function

Источник

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

(function (foo, bar) {
console.log(typeof arguments); // ?

arguments[0] = 42;
console.log(foo); // ?
})(10, 20);

А также покажу интересную идею-библиотеку

function test (foo, bar) {
Args(arguments).defaults(100, 100);

return [foo, bar];
};

test( ); // 100, 100
test(15 ); // 15, 100
test(21, 42); // 21, 42

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

Что такое arguments

Это хэш. Обычный хэш, как var object = {}

(function () { console.log(
typeof arguments, // object
Object.getPrototypeOf(arguments) == Object.prototype // true
) })();

Сделать из него массив просто:

var array = Array.prototype.slice.call(arguments, 0);
// или покороче, но менее производительно:
var array = [].slice.call(arguments, 0);

Мы вызываем метод slice прототипа Array от лица arguments.

Что есть в arguments

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

var count = function () {
console.log(arguments.length);
};

count(); // 0
count(first, second); // 2

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

function one (foo) {};
function three (foo, bar, qux) {};

console.log( one.length); // 1
console.log(three.length); // 3

arguments.callee — ссылка на саму функцию.

function foo () {
console.log(arguments.callee === foo); // true
}

Таким образом можно проверить, передано ли правильное количество элементов, или нет:

function test (foo, bar, qux) {
return arguments.callee.length === arguments.length;
}

test(1); // false
test(1,2,3); // true

Аргументы в arguments

В arguments содержится также список переданных аргументов.

function test (foo, bar) {
console.log(foo, bar); // ‘a’, ‘b’
console.log(arguments[0], arguments[1]); // ‘a’, ‘b’
}
test(‘a’, ‘b’);

Теперь к интересному. Многие не знают, что объект arguments — содержит на самом деле ссылки, а не значения, и тесно связан с аргументами:

(function (foo) {
arguments[0] = 42;
console.log(foo); // 42!

foo = 20;
console.log(arguments[0]); // 20
})(5);

При этом связь достаточно крепкая:

function foo (qux) {
change(arguments);
return qux;
};

function change(a) {
a[0] = 42;
}

foo(10); // 42

Что из этого можно получить?

Во многих языках программирования есть «переменные по-умолчанию». К примеру, php:

function ($foo = 30, $bar = ‘test’) {
var_dump($foo);
var_dump($bar);
}

В javascript оно будет выглядеть как-то так:

function (foo, bar) {
if (typeof foo === ‘undefined’) foo = 30;
if (typeof bar === ‘undefined’) bar = ‘test’;

console.log(foo, bar);
}

Зная особенности arguments можно создать красивый интерфейс:

function test(foo, bar) {
Args(arguments).defaults(30, ‘test’);

console.log(foo, bar)
}

test(); // 30, ‘test’

С помощью такого кода:

function Args (args) {
if (this instanceof Args) {
this.args = args;
} else {
// Если создано не через new, а просто вызвана функция, создаем и возвращаем новый объект
return new Args(args);
}
};
Args.prototype = {
defaults: function () {
var defaults = arguments;
for (var i = defaults.length; i–;) {
if (typeof args[i] === ‘undefined’) args[i] = defaults[i];
}
return this;
}
};

Аналогично можно сделать автоматическое приведение типов:

function test(foo) {
Args(arguments)
.defaults(10)
.cast(Number);

console.log(foo)
}

test(‘0100’); // 100

Или Type Hinting:

function test(foo, bar) {
Args(arguments).types(Foo, Bar);

// code
}

test(new Foo(), new Bar());
test(1, 2); // Error

Из интересных идей — сообщение, что все аргументы обязательны:

function test (foo, bar, qux) {
Args(arguments).allRequired();
}

test(1,2,3); // success
test(1,2); // Error: 3 args required, 2 given

Заключение

Все эти идеи и возможности (и даже больше) я оформил в библиотеку — Args.js.
Согласен, что кое-какие вещи (как TypeHinting) не совсем подходят к идеологии языка. В то же время например defaults — очень удобная штука, имхо.
Пока что это прототип и, перед тем как вы будете его использовать — будьте уверены, что оно вам действительно нужно, а не что вы просто стараетесь из прекрасного языка сделать что-то похожее на C#.
Предлагаю обсудить, покритиковать код, найти пару багов и закоммитить несколько строк кода)

Args.js

К сожалению, из-за бага в трёх популярных браузерах(IE, Fx, Opera) я не смог добиться желаемого эффекта, полноценно самое вкусное заработало только в Chrome (ну по крайней мере в node.js работать будет)). Надеюсь, решим эту проблему вместе.

UPD: В комментах выяснили, что таки это бага Хрома, но, зато, какая приятная! Спасибо jamayka

Источник

JavaScript Function

Определение и применение

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

Объект arguments является локальной переменной, которая доступна во всех функциях, за исключением стрелочных, она позволяет ссылаться внутри функции на аргументы функции с помощью объекта arguments. Этот объект содержит запись для каждого аргумента, переданного в функцию, индекс первой записи начинается с 0 и соответствует первому аргументу функции, индекс 1 соответствует второму аргументу функции и так далее.

Например:

function f( a, b, c) {
arguments[0]; // соответствует первому аргументу функции
arguments[1]; // соответствует второму аргументу функции
arguments[2]; // соответствует третьему аргументу функции
}

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

function f( a) {
arguments[0] == 100; // задаем значение первого аргумента функции
}

Как мы уже рассмотрели выше объект arguments не является массивом, по этой причине он не имеет методов и свойств объекта Array, за исключением свойства length. Чтобы преобразовать объект arguments в массив вы можете воспользоваться спред (spread) оператором, или методом from()ECMAScript 2015, который преобразует и возвращает новый массив из массивоподобного, или итерируемого объекта:

// создаем функцию, которая выводит в консоль массив, содержащий переданные аргументы этой функции
function f( a, b, c) {
const args = […arguments]; // используем спред оператор
const args2 = Array.from( arguments ); // используем метод from
console.log( args, args2 ); // выводим в консоль значение переменных
}

f( 10,20,30 ); // возвращаемое значение [10, 20, 30] [10, 20, 30]

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

function f( a, b) {
// проверяем количество переданных аргументов
arguments.length == 2 ? console.log( “да” ) : console.log( “нет”);
}

f( 10,20 ); // да
f( 10,20,30 ); // нет

Вы можете определить тип передаваемых аргументов следующим образом:

function f( a, b) {
console.log( typeof arguments ); // выводим в консоль тип объекта arguments
console.log( typeof arguments[0] ); // выводим в консоль тип первого аргумента
console.log( typeof arguments[1] ); // выводим в консоль тип второго аргумента
}

f( [1,2,3], 5 );
object
object
number

f( {}, “str”);
object
object
string

f( ()=>0, 5 );
object
function
number

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

JavaScript синтаксис:

arguments

например:
arguments[0] // первый аргумент функции
arguments[1] // второй аргумент функции
arguments[2] // третий аргумент функции

Версия JavaScript

1.1 (ECMAScript 1st Edition)

Свойства объекта

СвойствоОписание
calleeСвойство ссылается на выполняемую в данный момент функцию. Пятое издание ECMAScript (ES5) запрещает его использование в строгом режиме (strict mode).
lengthСвойство содержит количество аргументов, переданных функции. Это значение может быть больше или меньше, чем количество определенное при создании функции.
[@@iterator]Начальным значением свойства @@iterator является тот же объект функции, что и начальное значение свойства values объекта Array (метод возвращает новый объект итератора массива, содержащий значения для каждого индекса в массиве).

Пример использования

Вычисление факториала с использованием свойства callee объекта arguments:

var factorial = function( num ) {
if (num 1) return 1;
return num * arguments.callee(num-1 );
};

factorial(0); // возвращаемое значение 1
factorial(3); // возвращаемое значение 6
factorial(5); // возвращаемое значение 120
factorial(10); // возвращаемое значение 3628800

Обратите внимание, что в строгом режиме (strict mode), использование свойства callee запрещено.

В следующем примере расссмотрено как с помощью цикла for..of итерироваться по объекту arguments:

function f() {
console.log( arguments.length ); // выводим в консоль количество переданных аргументов функции
for ( let char of arguments ) {
console.log( char ); // выводим в консоль каждый переданный аргумент
}
}

f(“a”, “b”, “c”);
3
a
b
c

JavaScript Function

Источник

Именованные функции (FunctionDeclaration)

/*

функция sum

нормально отработает

*/

var a = sum(2,2)

function sum(x,y) {

   return x+y

}

Анонимные функции (FunctionExpression)

/*

будет ошибка,

т.к sum еще не существует

*/

var a = sum(2,2)

var sum = function(x,y) {

   return x+y

}

Анонимная самовызывающаяся функция

/*

позворяет изолировать код от глобальной видимости

*/

(function(){

    var i=1;

    console.log(“Анонимная самовызывающаяся функция”);

})();

console.log(i); // i is not defined

Функции — объекты

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/*

возможность передавать значение свойства в функции как в объект

*/

function func() {

   return …

}

func.test = 13

alert(func.test) // 13

function func() {

    var funcObj = arguments.callee; // получаем объект функции со всеми методами и свойствами

    funcObj.test++; // обращаемся к локальной области

    alert(funcObj.test);

}

func.test = 1

func() // 2

func() // 3

Области видимости

/*

локальная область видимости функции определяется фигурными скобками и объявлением var, let, const

*/

var x = 10;

function a() {

    // присвоить значение локальной переменной можно до ее объявления

    z=5;

    console.log(x+z);

    // объявить локальную переменную можно в любой части области (она поднимется вверх)

    var z;

}

delete z // очистим на всякий случай глобальную z

a() // 15

console.log(window.z) // => undefined, т.к z была задана локально

Параметры функции

/*

передаем функции параметры, обрабатываем и возвращаем результат

*/

var run = function(distance, speed) {

    var time;

    var speed = speed||10;

    var time=distance/speed;

    return time;

}

console.log(run(10)); // 1

console.log(run(10,5)); // 2

console.log(run(10,5,46,11)); // 2

console.log(run()); // NaN

Неопределенным числом параметров

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

/*

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

при этом он поход на массив но не содержит методов присущих массиву (.push, .pop),

имеет длинну в свойстве length

и ссылку на саму функцию в свойстве callee

*/

function func() {

    for(vari=0;i<arguments.length;i++) {

       alert(“arguments[“+i+”] = “+arguments[i])

   }

}

func(‘a’,’b’,true)

console.log(arguments[0]); // a

console.log(arguments[1]); // b

console.log(arguments[2]); // true

/*

внутри функции можно создать массив из переданных аргументов

*/

var args = Array.prototype.slice.call(arguments); // теперь args – настоящий массив аргументов

args.shift() // удаляем первый элемент массива

(function(args) {

})(); //используем аргументы во вложенной функции

Передача функции по ссылке

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

/*

Передача функции по ссылке

*/

var map = function(func, arr) {

    var result= [ ]

    for(vari=0; i<arr.length; i++) {

        result[i] =func(arr[i])

     }

    return result

}

// передаем функцию внутрь массива по ссылке

function run(a) { return a*3; }

console.log(map( run , [1,2,3])); // [3, 6, 9]

// передаем ананимную функцию как аргумент в вызове

console.log(map( function (a) { return a*3 } , [1,2,3])); // [3, 6, 9]

Сворачивание параметров в объект

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

/*

Сворачивание параметров в объект через “keyword arguments”

если в функции много необязательных параметров func(1,2,null,null,true,null)

*/

function resize(setup) {

    var animate = setup.animate || true,

    toHeight=setup.toHeight||10,

    toWidth=setup.toHeight||20;

}

// передаем параметры по ключу в разном порядке

resize({toWidth: 100, animate: true, toHeight: 25})

===

var array = {toWidth: 100, animate: true, toHeight: 25};

resize(array);

Источник