引数を別のJavaScript関数に渡す


386

私は成功せずに次のことを試しました:

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

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

a(1,2,3);

関数aでは、argumentsキーワードを使用して引数の配列にアクセスできますが、関数bではこれらは失われます。私がやろうとしているような別のJavaScript関数に引数を渡す方法はありますか?


3
@ BobStein-VisiBone同意。さらに、これarguments実際には配列ではなく(むしろ、配列のようなセマンティクスを実装するオブジェクト)、したがって、実際の配列と同じように使用できるかどうかは、一見すると完全に明確ではありません。
ジュール、

@Julesは、これらすべての年月を経て、引き続き再開することを投票しています。他の人の貴重な作品を燃やすためのバッジは何ですか?移動するそれらの多く。
ボブスタイン

回答:


542

次のよう.apply()arguments、function 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);
ニック・Craver

18
しかしapply、このように使用するとb(たとえば、オブジェクトの内部関数である場合)
スコープが台無しに

3
@vsync良い点ですが、問題は簡単に解決できます。適用する最初の引数としてオブジェクトを渡します。
Tad Lispy 2013

11
"args"と "arguments"を一緒に使用しても意味がありません...
dude

3
しかし、「this」はbの元のthis以外のものに変更される可能性があります。
trusktr 2015

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をまだ使用している場合、このスニペットは構文エラーを返します。

編集者注:スニペットではを使用しているため、結果を表示するにはブラウザのJSコンソールを開くconsole.log()必要があります - ページはめ込み結果はありません

この結果が表示されます:

スプレッド演算子の引数の例の画像

つまり、配列を使用している場合、spread演算子はさまざまな目的に使用できるため、関数の引数にも使用できます。公式ドキュメントで説明されている同様の例を見ることができます:Restパラメーター


6
これは非常に優れた演算子であり、私はそれを使用することを本当に楽しみにしています。しかし、それはまだ起こりません。現在、spreadオペレーターをサポートしている唯一のブラウザーはFFです。最新の完全なデータについては、互換性の表を参照してください:kangax.github.io/compat-table/es6/#spread_%28...%29_operator
TMG

10
なぜそれを使用すべきではないのですか?babelを使用してトランスパイルするのは比較的簡単で、すべての新機能が得られ、古いブラウザーとの互換性が大幅に向上します。
adgelbfish 2017

これは、矢印演算子で定義された関数で機能するため、最初のソリューションよりも優れています。
sarfata

関数...argsには必要ありませんa。あなただけの引数なしで機能させるとする上でそれらを渡すことができb...arguments
cronoklee

1
この回答を読んでいる人へ:@cronokleeのコメントとは逆に、ネストされた関数がある場合は、入力...argsとして明示的に指定するaことが重要になります。
Arshia001

81

他の回答のどれも提供しないという説明は、元の引数まだ利用可能ですが、argumentsオブジェクトの元の位置にはありません。

argumentsオブジェクトは、関数に提供される各実際のパラメータに対して1つの元素を含みます。あなたが呼び出すとa数字:あなたは3つの引数を供給し12、、と3。したがって、argumentsが含まれています[1, 2, 3]

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

bただし、を呼び出すときは、引数を1つだけ渡します:aargumentsオブジェクト。つまり、argumentsが含まれます[[1, 2, 3]](つまり、aargumentsオブジェクトである1つの要素であり、への元の引数を含むプロパティがありますa)。

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

a(1,2,3);

@Nickが示すように、を使用applyargumentsて、呼び出しでセットオブジェクトを提供できます。

以下は同じ結果を達成します:

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

しかしapply、一般的なケースでは正しい解決策です。


あなたは常に渡す必要thisapply
Flimm

1
@Flimm-はい、引数は2番目の引数なので、最初の引数には何かが必要です(nullの場合もあります)。
RobG、2015

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.