Передайте невідому кількість аргументів у функцію javascript


84

Чи є спосіб передати невідому кількість аргументів, таких як:

var print_names = function(names) {
    foreach(name in names) console.log(name); // something like this
}

print_names('foo', 'bar', 'baz');

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



Наразі відповідь загальнодоступного заміщення є єдиною, яка описує, як передати невідому кількість аргументів (у виклик функції) (використовуючи .apply). Інші показують, як читати невідому кількість аргументів (зсередини функції) (за допомогою arguments).
Ben J

Відповіді:


146

ES3 (або ES5 або Javascript старої школи)

Ви можете отримати доступ до аргументів, переданих будь-якій функції javascript через магічний argumentsоб'єкт, який поводиться подібно до масиву. Використання argumentsвашої функції могло б виглядати так

var print_names = function() {
     for (var i=0; i<arguments.length; i++) console.log(arguments[i]);
}

Важливо зазначити, що argumentsце не масив. У MDC є хороша документація: https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Functions#Using_the_arguments_object

Якщо ви хочете включити argumentsв масив , так що ви можете робити такі речі .slice(), і .push()т.д., використовуйте що - щось на зразок цього:

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

ES6 / Машинопис

Є кращий спосіб! Нова функція параметрів відпочинку має вашу спину:

var print_names = function(...names) {
    for (let i=0; i<names.length; i++) console.log(names[i]);
}

3
Дякую за таку розгорнуту і водночас коротку + просту відповідь :)
Месе

1
Посилання на ES6 spread syntaxтут є досить неправильним. Це rest parameterприклад, який ви дали. Хороша відповідь, але заплутане тим, що на нього посилаються якspread
Дренай

Дякую за вашу відповідь! Я знайшов, що це корисна стаття, яка пояснює, що відбувається Array.prototype.slice.call(arguments): medium.com/@andrewsburke/…
AnnieP

22

ES6 / ES2015

Скористайтеся перевагами синтаксису параметру rest .

function printNames(...names) {
  console.log(`number of arguments: ${names.length}`);
  for (var name of names) {
    console.log(name);
  }
}

printNames('foo', 'bar', 'baz');

Існують три основні відмінності між параметрами відпочинку та об’єктом аргументів:

  • параметри відпочинку - це лише ті, які не отримали окремого імені, тоді як об’єкт аргументів містить усі аргументи, передані функції;
  • об'єкт аргументів не є реальним масивом, тоді як інші параметри - це екземпляри масиву, тобто методи, такі як сортування, відображення, forEach або поп, можуть бути застосовані до нього безпосередньо;
  • об'єкт аргументи має додаткову функціональність, специфічну для нього саму (наприклад, властивість виклику).

Це має сенс для веб-розробки, яка зазвичай використовує загальноприйнятий синтаксис PHP.
Дадан



6

Існує прихований об'єкт, який передається кожній функції у JavaScript, що називається arguments.

Ви просто використовували б, arguments.lengthщоб отримати кількість аргументів, переданих функції.

Для ітерації аргументів ви використовуєте цикл:

for(var i = arguments.length; i--) {
   var arg = arguments[i];
}

Зверніть увагу, що argumentsце не справжній масив, тому, якщо він вам потрібен як масив, ви перетворите його таким чином:

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

3
Просто зверніть увагу , що це не є «реальним» масив, це «масив типу» об'єкт (з деякими спеціальними властивостями), але використовувати «методи Array» на ньому, вам потрібно буде перетворити його, наприклад var args = Array.prototype.slice.call(arguments);, var args = Array.apply(null, arguments);і т.д. , є багато способів ...
Крістіан Сальвадо,

4

arguments.length. на ньому можна використовувати цикл for.

(function () {
    for (var a = [], i = arguments.length; i--;) {
        a.push(arguments[i]);
    };
    return a;
})(1, 2, 3, 4, 5, 6, 7, 8)

@meder, я люблю використовувати такі анонімні функції. Гарний приклад! Крім того, вам не вистачає там крапки з комою?
Jacob Relkin

здається, працює нормально, як є.
meder omuraliev

@meder, Вставка крапки з комою в JavaScript #ftf
Якоб Рєлкін,

@meder, справді, просто крапка з комою після forблоку насправді не потрібна, однак я додав би її в кінці останнього рядка.
Крістіан С. Сальвадо,

1
@weng, це про FunctionExpressionvs FunctionDeclaration, перегляньте цю статтю .
Крістіан Сальвадо,

2

Зараз набагато краще для ES6

function Example() {
    return {
        arguments: (...args) =>{
            args.map(a => console.log());
        }
    }
}

var exmpl = new Example();
exmpl.arguments(1, 2, 3, 'a', 'b', 'c');

Сподіваюся, це допоможе


0

Параметри відпочинку в ES6

const example = (...args) => {
  for (arg in args) {
    console.log(arg);
  }
}

Примітка: ви можете передавати звичайні параметри до інших параметрів

const example = (arg1, ...args) => {
  console.log(arg1);
  for (arg in args) {
    console.log(arg);
  }
}

0

Ви можете використовувати оператор розповсюдження / відпочинку, щоб зібрати ваші параметри в масив, і тоді lengthмасивом буде кількість переданих вами параметрів:

function foo(...names) {
    console.log(names);
    return names;
}

console.log(foo(1, 2, 3, 4).length);

За допомогою BabelJS я перетворив функцію на oldschool JS:

"use strict";

function foo() {
  for (var _len = arguments.length, names = new Array(_len), _key = 0; _key < _len; _key++) {
    names[_key] = arguments[_key];
  }

  console.log(names);
  return names;
}

0

Ви можете створити функцію за допомогою оператора розповсюдження / відпочинку, і з цього моменту ви досягли своєї мети. Будь ласка, погляньте на фрагмент нижче.

const print_names = (...args) => args.forEach(x => console.log(x));


-4

Мені подобається робити це:

Це не допоможе, якщо ви не знаєте кількість аргументів, але це допомагає, якщо ви не хочете запам’ятовувати їх порядок.

/**
 *  @param  params.one        A test parameter
 *  @param  params.two        Another one  
 **/
function test(params) {

    var one = params.one;
    if(typeof(one) == 'undefined') {
        throw new Error('params.one is undefined');
    }

    var two = params.two;
    if(typeof(two) == 'undefined') {
        throw new Error('params.two is undefined');
    }
}

1
Питання було про невідому кількість аргументів.
Дизайн Адріана
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.