Передача масиву як функціонального параметра в JavaScript


291

Я б хотів викликати функцію, використовуючи масив як параметри:

const x = ['p0', 'p1', 'p2'];
call_me(x[0], x[1], x[2]); // I don't like it

function call_me (param0, param1, param2 ) {
  // ...
}

Чи є кращий спосіб передачі вмісту з xв call_me()?

Відповіді:


422
const args = ['p0', 'p1', 'p2'];
call_me.apply(this, args);

Див. Документи MDN для Function.prototype.apply().


Якщо середовище підтримує ECMAScript 6, ви можете замість цього використовувати аргумент :

call_me(...args);

9
Як бічна примітка, якщо хтось хоче замість цього передати асоціативний масив (названі ключі), тоді використовує об’єкт. Походить із PHP (і завжди призводив до цієї теми від Google), це знадобило мені час, щоб зрозуміти. Потім ви можете передавати весь об'єкт як параметр. w3schools.com/js/js_objects.asp
timhc22

Дякуємо, що вказали на аргумент "розповсюдження"! Не знав про це.
Томас Ан

@timhc - коментар з вашої сторони примітки інтригує, але я не можу його розібрати (я працюю через noob JavaScript через пару навчальних посібників). У JS асоціативний масив є об'єктом згідно кількох навчальних посібників.
NateT

@ timhc22, і при використанні об'єкта json для передачі в якості параметра функції не забудьте знищення параметрів для кращої читабельності
Мухаммад Омер Аслам

113

Чому ти не передаєш весь масив і не обробиш його за потребою всередині функції?

var x = [ 'p0', 'p1', 'p2' ]; 
call_me(x);

function call_me(params) {
  for (i=0; i<params.length; i++) {
    alert(params[i])
  }
}

37
Це тому, що я не можу змінити call_me (). Це визначено в якійсь іншій бібліотеці, і не можна возитися з API.
Роберт

62
+1, оскільки, незважаючи на те, що він не відповідає на початкове запитання, це, мабуть, те, що шукали 100 К + людей, які переглядали цю сторінку
Ішикава

Чи може хтось пояснити, що робить рядок "call_me (x)"? Здається, це ім'я функції без ключового слова функції? Що саме це робить?
плив

1
@swam Це виклик call_meфункції. Просто не вистачає крапки з комою в кінці.
SantiBailors

@swam він вводить у виконання оголошену функцію call_me (params).
Хуліо Родрігес

43

Якщо припустити, що call_me є глобальною функцією, тому ви не очікуєте, що це буде встановлено.

var x = ['p0', 'p1', 'p2'];
call_me.apply(null, x);

41

У стандарті ES6 є новий оператор розповсюдження, ... який робить саме це.

call_me(...x)

Його підтримують усі основні браузери, крім IE.

Оператор розповсюдження може зробити багато інших корисних речей, а пов'язана документація справді добре справляється з цим.



7

Як відповів @KaptajnKold

var x = [ 'p0', 'p1', 'p2' ];
call_me.apply(this, x);

І вам також не потрібно визначати всі параметри функції call_me. Можна просто використовуватиarguments

function call_me () {
    // arguments is a array consisting of params.
    // arguments[0] == 'p0',
    // arguments[1] == 'p1',
    // arguments[2] == 'p2'
}

4
Це така погана практика ... ви не зможете побачити, що потрібна функція, і кожен параметр є необов'язковим, якщо ви подивитеся на функцію.
Робін

3

Зверніть увагу на це

function FollowMouse() {
    for(var i=0; i< arguments.length; i++) {
        arguments[i].style.top = event.clientY+"px";
        arguments[i].style.left = event.clientX+"px";
    }

};

// ---------------------------

html-сторінка

<body onmousemove="FollowMouse(d1,d2,d3)">

<p><div id="d1" style="position: absolute;">Follow1</div></p>
<div id="d2" style="position: absolute;"><p>Follow2</p></div>
<div id="d3" style="position: absolute;"><p>Follow3</p></div>


</body>

може викликати функцію з будь-якими Args

<body onmousemove="FollowMouse(d1,d2)">

або

<body onmousemove="FollowMouse(d1)">

Це однозначно є частиною відповіді. "Аргументи", безумовно, потрібні, щоб повернути масив після виклику. Дякую!
FlorianB

2

Аргументами функції також можуть бути масиви:

function foo([a,b,c], d){
  console.log(a,b,c,d);
}

foo([1,2,3], 4)

Звичайно, можна також використовувати спред :

function foo(a, b, c, d){
  console.log(a, b, c, d);
}

foo(...[1, 2, 3], 4)


2

Під час використання оператора спред слід зазначити, що він повинен бути останнім або єдиним пройденим параметром. Інакше це не вдасться.

function callMe(...arr){ //valid arguments
    alert(arr);
}

function callMe(name, ...arr){ //valid arguments
    alert(arr);
}

function callMe(...arr, name){ //invalid arguments
    alert(arr);
}

Якщо вам потрібно передати масив як вихідний аргумент, ви можете зробити:

function callMe(arr, name){
    let newArr = [...arr];
    alert(newArr);
}

1

ви можете використовувати оператор розповсюдження в більш базовій формі

[].concat(...array)

у випадку функцій, які повертають масиви, але, як очікується, передаються як аргументи

Приклад:

function expectArguments(...args){
  return [].concat(...args);
}

JSON.stringify(expectArguments(1,2,3)) === JSON.stringify(expectArguments([1,2,3]))

0

Відповідь вже була дана, але я просто хочу дати свій шматок пирога. Те, що ви хочете досягти, називається method borrowingв контексті JS, що коли ми беремо метод з об'єкта і називаємо його в контексті іншого об'єкта. Досить звичайно приймати методи масиву і застосовувати їх до аргументів. Дозвольте навести вам приклад.

Отже, у нас є "супер" хеш-функція, яка бере два числа як аргумент і повертає хеш-рядок "супер безпечного":

function hash() {
  return arguments[0]+','+arguments[1];
}

hash(1,2); // "1,2" whoaa

Поки що добре, але у нас мало проблем з вищезазначеним підходом, він обмежений, працює лише з двома числами, це не динамічно, давайте змусимо його працювати з будь-яким числом і плюс вам не потрібно передавати масив (ви можете якщо ви все-таки наполягаєте). Гаразд, достатньо поговорити, будемо битися!

Природним рішенням буде використання arr.joinметоду:

function hash() {
  return arguments.join();
}

hash(1,2,4,..); //  Error: arguments.join is not a function

О, чоловіче. На жаль, це не вийде. Оскільки ми називаємо хеш (аргументи) і об'єкт аргументів є ітерабельним і подібним до масиву, але не є реальним масивом. Як щодо нижченаведеного підходу?

function hash() {
  return [].join.call(arguments);
}

hash(1,2,3,4); // "1,2,3,4" whoaa

Трюк називається method borrowing.

Ми запозичаємо joinметод із звичайного масиву [].join.та використовуємо [].join.callдля запуску в контексті arguments.

Чому це працює?

Це тому, що внутрішній алгоритм нативного методу arr.join(glue) дуже простий.

З специфікації майже «як є»:

Let glue be the first argument or, if no arguments, then a comma ",".
Let result be an empty string.
Append this[0] to result.
Append glue and this[1].
Append glue and this[2].
Do so until this.length items are glued.
Return result.

Таким чином, технічно він приймає це і приєднується до цього [0], цього [1]… і т.д. разом. Це навмисно написано так, що дозволяє будь-який подібний масив (не випадковість, багато методів слідують цій практиці). Ось чому це теж працюєthis=arguments.

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