it-swarm.com.ru

Можно ли отправить переменное число аргументов в функцию JavaScript?

Можно ли отправить переменное число аргументов в функцию JavaScript из массива? 

var arr = ['a','b','c']

var func = function()
{
    // debug 
    alert(arguments.length);
    //
    for(arg in arguments)
        alert(arg);
}

func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'

Недавно я написал много Python, и это замечательный способ иметь возможность принимать varargs и отправлять их. например.

def func(*args):
   print len(args)
   for i in args:
       print i

func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(*arr) // prints 4 which is what I want, then 'a','b','c','d'

Возможно ли в JavaScript отправить массив для обработки как массив аргументов? 

147
Fire Crow

Использовать применить :

var arr = ['a','b','c'];

var func = function() {
  alert(arguments.length);

  for(var i = 0; i < arguments.length; i++) {
    alert(arguments[i]);
  }

};

func.apply(null, arr);

Обратите внимание, что null используется в качестве первого аргумента применения, что задает для ключевого слова this глобальный объект (окно) внутри func.

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

var argsArray = Array.prototype.slice.call(arguments);

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

var test = function (one, two, three) {}; 
test.length == 3;

Но в любом случае вы можете передать произвольное количество аргументов ...

168
CMS

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

Чтобы передать массив arguments в «распакованном» виде, вы можете использовать apply, например так (c.f. Functional Javascript ):

var otherFunc = function() {
   alert(arguments.length); // Outputs: 10
}

var myFunc = function() {
  alert(arguments.length); // Outputs: 10
  otherFunc.apply(this, arguments);
}
myFunc(1,2,3,4,5,6,7,8,9,10);
68
danben

Операторы splat и spread являются частью ES6, планируемой следующей версии Javascript. Пока их поддерживает только Firefox. Этот код работает в FF16 +:

var arr = ['quick', 'brown', 'lazy'];

var sprintf = function(str, ...args)
{
    for (arg of args) {
        str = str.replace(/%s/, arg);
    }
    return str;
}

sprintf.apply(null, ['The %s %s fox jumps over the %s dog.', ...arr]);
sprintf('The %s %s fox jumps over the %s dog.', 'slow', 'red', 'sleeping');

Обратите внимание на синтаксис awkard для распространения. Обычный синтаксис sprintf('The %s %s fox jumps over the %s dog.', ...arr); - пока не поддерживается . Вы можете найти таблицу совместимости ES6 здесь .

Обратите внимание также на использование for...of , еще одного дополнения ES6. Использование for...in для массивов - это плохая идея .

21
Tgr

Начиная с ES2015, существует два метода.

Объект arguments

Этот объект встроен в функции и, соответственно, ссылается на аргументы функции. Технически, однако, это не массив, поэтому типичные операции с массивами не будут работать с ним. Предлагаемый метод заключается в использовании Array.from или оператора распространения для создания массива из него.

Я видел другие упоминания ответов с использованием slice. Не делай этого. Это предотвращает оптимизацию (источник: MDN ).

Array.from(arguments)
[...arguments]

Однако я бы сказал, что arguments проблематичен, поскольку скрывает то, что функция принимает в качестве входных данных. Функция arguments обычно пишется так:

function mean(){
    let args = [...arguments];
    return args.reduce((a,b)=>a+b) / args.length;
}

Иногда заголовок функции пишется следующим образом для документирования аргументов в стиле C:

function mean(/* ... */){ ... }

Но это редко.

Что касается того, почему это проблематично, возьмем C, например. C обратно совместим с древним пре-ANSI диалектом языка, известного как K & R C. K & R C позволяет прототипам функций иметь пустой список аргументов.

int myFunction();
/* This function accepts unspecified parameters */

ANSI C предоставляет возможность для varargs (...) и void для указания пустого списка аргументов.

int myFunction(void);
/* This function accepts no parameters */

Многие люди непреднамеренно объявляют функции со списком аргументов unspecified (int myfunction();), когда ожидают, что функция примет нулевые аргументы. Технически это ошибка, потому что функция будет принимать аргументы. Любое их количество.

Правильная функция varargs в C принимает форму:

int myFunction(int nargs, ...);

И в JavaScript действительно есть что-то похожее на это.

Оператор распространения / Параметры покоя

Я уже показал вам оператор спреда.

...name

Он довольно универсален и может также использоваться в списке аргументов функции («параметры покоя»), чтобы задавать переменные в хорошо документированном виде:

function mean(...args){
    return args.reduce((a,b)=>a+b) / args.length;
}

Или как лямбда-выражение:

((...args)=>args.reduce((a,b)=>a+b) / args.length)(1,2,3,4,5); // 3

Я предпочитаю спред оператора. Это чисто и самодокументировано.

8
Braden Best

Функция apply принимает два аргумента; объект this будет связан с аргументами, представленными в виде массива.

some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"
7
August Lilleaas

Это называется оператором splat. Вы можете сделать это в JavaScript, используя apply:

var arr = ['a','b','c','d'];
var func = function() {
    // debug 
    console.log(arguments.length);
    console.log(arguments);
}
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'
func.apply(null, arr); 
5
Chandra Patni

С ES6 вы можете использовать остальные параметры для varagrs. Это берет список аргументов и преобразует его в массив.

function logArgs(...args) {
    console.log(args.length)
    for(let arg of args) {
        console.log(arg)
    }
}
4
theres.yer.problem

Это пример программы для вычисления суммы целых чисел для переменных аргументов и массива на целых числах. Надеюсь это поможет.

var CalculateSum = function(){
    calculateSumService.apply( null, arguments );
}

var calculateSumService = function(){
    var sum = 0;

    if( arguments.length === 1){
        var args = arguments[0];

        for(var i = 0;i<args.length; i++){
           sum += args[i]; 
        }
    }else{
        for(var i = 0;i<arguments.length; i++){
           sum += arguments[i]; 
        }        
    }

     alert(sum);

}


//Sample method call

// CalculateSum(10,20,30);         

// CalculateSum([10,20,30,40,50]);

// CalculateSum(10,20);
2
streak
(function(window) {
  var proxied = window.alert;
  window.alert = function() {
    return proxied.apply(window, arguments);
  };
}(this));

alert(13, 37);
2
yckart

Для тех, кто был перенаправлен сюда из Передача переменного количества аргументов из одной функции в другую (которая должна быть помечена как not как дубликат этого вопроса):

Если вы пытаетесь передать переменное число аргументов из одной функции в другую, начиная с JavaScript 1.8.5, вы можете просто вызвать apply() во второй функции и передать параметр arguments:

var caller = function()
{
    callee.apply( null, arguments );
}

var callee = function()
{
    alert( arguments.length );
}

caller( "Hello", "World!", 88 ); // Shows "3".

Примечание: Первый аргумент - это параметр this, который нужно использовать. Передача null вызовет функцию из глобального контекста, то есть как глобальную функцию вместо метода некоторого объекта.

Согласно этому документу , спецификация ECMAScript 5 переопределила метод apply(), чтобы принимать любой "универсальный объект, похожий на массив", а не только массив. Таким образом, вы можете напрямую передать список arguments во вторую функцию.

Протестировано в Chrome 28.0, Safari 6.0.5 и IE 10. Попробуйте это с this JSFiddle .

1
andrewtc

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

Например.:

var arr = ["Hi","How","are","you"];

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

applyTest.apply(null,arr);
0
Abhijit

Вы хотите, чтобы ваша функция реагировала на аргументы массива или переменные? Если последнее, попробуйте:

var func = function(...rest) {
  alert(rest.length);

  // In JS, don't use for..in with arrays
  // use for..of that consumes array's pre-defined iterator
  // or a more functional approach
  rest.forEach((v) => console.log(v));
};

Но если вы хотите обработать аргумент массива

var fn = function(arr) {
  alert(arr.length);

  for(var i of arr) {
    console.log(i);
  }
};
0
Dev Yego