配列から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'
最近多くのPythonを書きましたが、可変引数を受け入れて送信できるのは素晴らしいパターンです。例えば.
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'
JavaScriptで処理される配列を送信することは可能ですか?as arguments配列?
Update:ES6以降、単純に spread構文 when関数を呼び出す:
func(...arr);
ES6では、引数を配列として扱うことも想定しているため、パラメーターリストでスプレッド構文を使用することもできます。次に例を示します。
function func(...args) {
args.forEach(arg => console.log(arg))
}
const values = ['a', 'b', 'c']
func(...values)
func(1, 2, 3)
また、最初の2つの引数を別々に受け取り、残りを配列として受け取りたい場合など、通常のパラメーターと組み合わせることができます。
function func(first, second, ...theRest) {
//...
}
そして、おそらくあなたにとって便利です。関数が期待する引数の数を知ることができます:
var test = function (one, two, three) {};
test.length == 3;
とにかく、任意の数の引数を渡すことができます...
Spread構文はapply
よりも短くて「甘い」ため、関数呼び出しでthis
の値を設定する必要がない場合は、これが方法です。
以下に apply の例を示します。これは前者の方法です。
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
を使用することをお勧めしますandthis
値を設定します。 apply
は最初の引数としてthis
値であり、関数呼び出しで使用されます。非厳密コードでnull
を使用する場合、this
キーワードは、厳格モードで、func
内のグローバルオブジェクト(ウィンドウ)を参照します。明示的に「use strict」を使用するか、ESモジュールで、null
が使用されます。
また、 arguments
オブジェクトは実際には配列ではないことに注意してください。次の方法で変換できます。
var argsArray = Array.prototype.slice.call(arguments);
ES6では:
const argsArray = [...arguments] // or Array.from(arguments)
しかし、最近では、spread構文のおかげでarguments
オブジェクトを直接使用することはほとんどありません。
実際には、任意のjavascript関数に必要な数の値を渡すことができます。明示的に名前が付けられたパラメーターは最初のいくつかの値を取得しますが、すべてのパラメーターは引数配列に格納されます。
引数配列を「アンパック」形式で渡すには、次のようにapplyを使用できます(c.f. 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);
splat および spread 演算子は、Javascriptの予定されている次のバージョンである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');
スプレッドのawkard構文に注意してください。 sprintf('The %s %s fox jumps over the %s dog.', ...arr);
の通常の構文は まだサポートされていません です。 ここにES6互換性テーブル があります。
for...of
の使用にも注意してください。これは別のES6の追加です。配列にfor...in
を使用するのは 悪い考え です。
ES2015現在、2つの方法があります。
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 */
多くの人は、関数が引数をとらないと期待しているときに、unspecified
引数リスト(int myfunction();
)で関数を誤って宣言します。これは技術的にはバグです。関数は引数を受け入れるためです。それらの任意の数。
Cの適切なvarargs
関数は次の形式を取ります。
int myFunction(int nargs, ...);
JavaScriptは実際にこれに似たものを持っています。
実際に、スプレッド演算子を既に示しました。
...name
これは非常に汎用性が高く、関数の引数リスト(「残りのパラメーター」)で使用して、適切に文書化された方法で可変引数を指定することもできます。
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
私はスプレッド演算子を非常に好みます。クリーンで自己文書化されています。
apply
関数は2つの引数を取ります。オブジェクトthis
はバインドされ、引数は配列で表されます。
some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"
splat
演算子と呼ばれます。 apply
を使用してJavaScriptで実行できます。
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
に rest parameters を使用できます。これは引数リストを受け取り、配列に変換します。
function logArgs(...args) {
console.log(args.length)
for(let arg of args) {
console.log(arg)
}
}
これは、可変引数の整数の合計と整数の配列を計算するためのサンプルプログラムです。お役に立てれば。
var CalculateSum = function(){
calculateSumService.apply( null, arguments );
}
var calculateSumService = function(){
var sum = 0;
if( arguments.length === 1){
var args = arguments[0];
for(var i = 0;i<args.length; i++){
sum += args[i];
}
}else{
for(var i = 0;i<arguments.length; i++){
sum += arguments[i];
}
}
alert(sum);
}
//Sample method call
// CalculateSum(10,20,30);
// CalculateSum([10,20,30,40,50]);
// CalculateSum(10,20);
(function(window) {
var proxied = window.alert;
window.alert = function() {
return proxied.apply(window, arguments);
};
}(this));
alert(13, 37);
ここからリダイレクトされた人のために 1つの関数から別の関数に可変数の引数を渡す (これはnotとしてマークされますこの質問の複製):
ある関数から別の関数に可変数の引数を渡そうとしている場合、JavaScript 1.8.5以降では、2番目の関数でapply()
を呼び出してarguments
パラメーターを渡すだけで済みます。
var caller = function()
{
callee.apply( null, arguments );
}
var callee = function()
{
alert( arguments.length );
}
caller( "Hello", "World!", 88 ); // Shows "3".
注:最初の引数は、使用するthis
パラメーターです。 null
を渡すと、グローバルコンテキストから関数が呼び出されます。つまり、何らかのオブジェクトのメソッドではなくグローバル関数として呼び出されます。
このドキュメント によれば、ECMAScript 5仕様は、厳密に配列ではなく、「汎用配列のようなオブジェクト」をとるようにapply()
メソッドを再定義しました。したがって、arguments
リストを2番目の関数に直接渡すことができます。
Chrome 28.0、Safari 6.0.5、およびIEでテスト済み10. 10. this JSFiddle で試してみてください。
はい、変数noを渡すことができます。関数への引数の。 apply
を使用してこれを実現できます。
例えば。:
var arr = ["Hi","How","are","you"];
function applyTest(){
var arg = arguments.length;
console.log(arg);
}
applyTest.apply(null,arr);
関数を配列引数または変数引数に反応させますか?後者の場合、試してください:
var func = function(...rest) {
alert(rest.length);
// In JS, don't use for..in with arrays
// use for..of that consumes array's pre-defined iterator
// or a more functional approach
rest.forEach((v) => console.log(v));
};
しかし、配列引数を処理したい場合
var fn = function(arr) {
alert(arr.length);
for(var i of arr) {
console.log(i);
}
};