[javascript] 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'

나는 최근에 많은 파이썬을 작성했으며 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'

자바 스크립트를 처리 할 배열 보내는 것이 가능 으로 인수 배열을?



답변

업데이트 : ES6부터 함수를 호출 할 때 간단히 스프레드 구문을 사용할 수 있습니다 .

func(...arr);

ES6은 또한 인수를 배열로 취급하려는 경우 매개 변수 목록에서 다음과 같은 스프레드 구문을 사용할 수도 있습니다.

function func(...args) {
  args.forEach(arg => console.log(arg))
}

const values = ['a', 'b', 'c']
func(...values)
func(1, 2, 3)

예를 들어 처음 두 인수를 개별적으로 받거나 나머지를 배열로 받으려면 일반 매개 변수와 결합 할 수 있습니다.

function func(first, second, ...theRest) {
  //...
}

함수가 예상하는 인수의 수를 알 수 있다는 점에서 유용 할 수 있습니다.

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

그러나 어쨌든 임의의 수의 인수를 전달할 수 있습니다 …

스프레드 구문은 짧고 “달콤하다”고 함수 호출에서 값 apply을 설정할 필요가없는 this경우이 방법이 사용됩니다.

다음은 적용 예입니다. 이전의 방법이었습니다.

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

function func() {
  console.log(this); // 'test'
  console.log(arguments.length); // 3

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

};

func.apply('test', arr);

요즘 난 단지 사용하는 것이 좋습니다 apply당신이 배열에서 임의의 인수 수를 통과해야하는 경우에만 설정된 this값입니다. apply는 IS 소요 this함수 호출에 사용되는 최초의 인수와 같은 값이 우리가 사용하는 경우, null비 엄격한 코드에서 this키워드는 글로벌 오브젝트 (창) 내부에 참조 할 funcStrict 모드에서, 명시 적으로 ‘사용하는 경우 엄격한 사용 ‘또는 ES 모듈에서 null사용됩니다.

또한 arguments객체는 실제로 배열이 아니라는 점에 유의하십시오 .

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

그리고 ES6에서 :

const argsArray = [...arguments] // or Array.from(arguments)

그러나 arguments스프레드 구문 덕분에 오늘날 객체를 직접 사용하는 경우는 거의 없습니다 .


답변

실제로 자바 스크립트 함수에 원하는만큼 많은 값을 전달할 수 있습니다. 명시 적으로 명명 된 매개 변수는 처음 몇 개의 값을 가져 오지만 모든 매개 변수는 인수 배열에 저장됩니다.

“unpacked”형식으로 arguments 배열을 전달하려면 apply를 사용할 수 있습니다 ( 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);


답변

플랫확산 운영자는 ES6, 자바 스크립트의 계획을 다음 버전의 일부입니다. 지금까지는 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');

스프레드에 대한 어색한 구문에 유의하십시오. 의 일반적인 구문 sprintf('The %s %s fox jumps over the %s dog.', ...arr);입니다 아직 지원되지 않습니다 . ES6 호환성 표는 여기에서 찾을 수 있습니다 .

for...of또 다른 ES6 추가 인의 사용에 주목하십시오 . for...in배열에 사용 하는 것은 나쁜 생각 입니다.


답변

apply함수는 두 가지 인수를 취합니다. 객체 this가 바인딩되고 인수가 배열로 표현됩니다.

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


답변

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는 K & R C로 알려진 고대의 ANSI 이전의 방언과 역 호환됩니다. K & R C는 함수 프로토 타입이 빈 인수 목록을 가질 수 있도록합니다.

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

ANSI C는 varargs( ...)에 대한 기능을 제공하고 void빈 인수 목록을 지정합니다.

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

많은 사람들 이 함수가 인수가 0이 될 것으로 예상 할 때 unspecified인수 목록 ( int myfunction();)을 사용하여 실수로 함수를 선언합니다 . 함수 인수 허용 하기 때문에 이것은 기술적으로 버그 입니다. 그것들의 수

varargsC 의 적절한 기능은 다음과 같은 형식을 취합니다.

int myFunction(int nargs, ...);

그리고 JavaScript는 실제로 이와 비슷한 것을 가지고 있습니다.

스프레드 연산자 / 휴면 파라미터

이미 스프레드 연산자를 보여 드렸습니다.

...name

그것은 매우 다재다능하고 함수의 argument-list ( “rest parameters”)에서 varargs를 잘 문서화 된 방식으로 지정하기 위해 사용될 수 있습니다 :

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

스프레드 연산자를 선호합니다. 깨끗하고 자체 문서화됩니다.


답변

이것을 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); 


답변

ES6에서는에 대한 나머지 매개 변수 를 사용할 수 있습니다 varagrs. 인수 목록을 받아서 배열로 변환합니다.

function logArgs(...args) {
    console.log(args.length)
    for(let arg of args) {
        console.log(arg)
    }
}