Передача аргументів вперед до іншої функції javascript


386

Я пробував наступне без успіху:

function a(args){
    b(arguments);
}

function b(args){
    // arguments are lost?
}

a(1,2,3);

У функції a я можу використовувати ключове слово аргументи для доступу до масиву аргументів, у функції b вони втрачаються. Чи є спосіб передачі аргументів іншій функції javascript, як я намагаюся це зробити?


3
@ BobStein-VisiBone погодився. Крім того, зауважте, що argumentsце насправді не масив (це, скоріше, об'єкт, що реалізує семантику, схожу на масив ), і тому на перший погляд не зовсім зрозуміло, чи можна його використовувати так само, як може бути власне масив.
Жуль

@Jules все ще голосує за повторне відкриття після всіх цих років. Який знак для спалювання цінних робіт інших людей? Дуже багато тих, хто обійде.
Боб Штейн

Відповіді:


542

Використовуйте .apply()для того самого доступу до argumentsфункції b, як цей:

function a(){
    b.apply(null, arguments);
}
function b(){
   alert(arguments); //arguments[0] = 1, etc
}
a(1,2,3);​

Ви можете перевірити це тут .


21
@Brett - Ви можете скопіювати його в масив, а потім маніпулювати цим, перш ніж передавати його, наприклад:var copy = [].slice.call(arguments); <remove what you want> myFunc.apply(this, copy);
Нік Крейвер

18
але використовуючи applyподібне, це може викрутити область b(якщо це наприклад якась внутрішня функція об'єкта)
vsync

3
@vsync хороший момент, але проблему легко вирішити: передайте об'єкт як перший аргумент, який слід застосувати.
Тад Ліспі

11
не має сенсу використовувати "аргументи" та "аргументи" разом ...
чувак

3
Але тоді "це" може бути змінено на щось інше, ніж оригінал b цього.
trusktr

223

Оператор розповсюдження

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

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

Приклад без використання applyметоду:

function a(...args){
  b(...args);
  b(6, ...args, 8) // You can even add more elements
}
function b(){
  console.log(arguments)
}

a(1, 2, 3)

Note Цей фрагмент повертає помилку синтаксису, якщо ваш браузер все ще використовує ES5.

Чи не Примітка редактора: Оскільки сніпетів використання console.log(), необхідно відкрити консоль JS в браузері, щоб побачити результат - буде немає результат на сторінці.

Він відобразить цей результат:

Зображення прикладу аргументів оператора Spread

Коротше кажучи, оператор розповсюдження може використовуватися для різних цілей, якщо ви використовуєте масиви, тому він також може бути використаний для аргументів функції, ви можете побачити подібний приклад, пояснений в офіційних документах: Параметри відпочинку


6
Це дуже приємний оператор, і я дуже з радістю використовую його. Однак це ще не відбудеться. Наразі єдиний браузер, який вже підтримує оператор розповсюдження, - це FF. Повні та
TMG

10
Чому його не слід використовувати? Транспірувати бабелом порівняно просто, ви отримуєте всі нові функції та набагато більшу сумісність зі старими браузерами.
adgelbfish

Це краще, ніж перше рішення, оскільки воно працює у функції, визначеній оператором стрілки.
сарфата

Вам не потрібно ...argsв aфункції. Ви можете просто створити функцію без аргументів і передавати їх bз...arguments
cronoklee

1
Для всіх, хто читає цю відповідь: На відміну від коментаря @ cronoklee, чітко вказавши ...argsяк aвведення, може бути важливим, якщо у вас є вкладені функції.
Arshia001

81

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

argumentsОб'єкт містить один елемент для кожного фактичного параметра , наданого функцією. При виклику aви ставите три аргументи: числа 1, 2, і, 3. Отже, argumentsмістить [1, 2, 3].

function a(args){
    console.log(arguments) // [1, 2, 3]
    b(arguments);
}

Коли ви телефонуєте b, ви передаєте рівно один аргумент: a's argumentsobject. Таким чином , argumentsмістить [[1, 2, 3]](тобто один елемент, який є a«s argumentsоб'єкт, який має властивість , що містить вихідні аргументи a).

function b(args){
    // arguments are lost?
    console.log(arguments) // [[1, 2, 3]]
}

a(1,2,3);

Як показав @Nick, ви можете використовувати applyдля надання заданого argumentsоб'єкта у виклику.

Наступний результат досягає:

function a(args){
    b(arguments[0], arguments[1], arguments[2]); // three arguments
}

Але чи applyє правильним рішенням у загальному випадку.


Ви завжди повинні переходити thisдо apply?
Flimm

1
@ Flimm - так, оскільки аргументи є другим аргументом, для першого аргументу повинно бути щось (воно може бути нульовим ).
RobG

0

спробуйте це

function global_func(...args){
  for(let i of args){
    console.log(i)
  }
}


global_func('task_name', 'action', [{x: 'x'},{x: 'x'}], {x: 'x'}, ['x1','x2'], 1, null, undefined, false, true)




//task_name
//action
//(2) [{...},
//    {...}]
//    {
//        x:"x"
//    }
//(2) [
//        "x1",
//        "x2"
//    ]
//1
//null
//undefined
//false
//true
//func
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.