回答:
もちろん、arguments
オブジェクトを使用してください。
function foo() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
arguments
特別な「配列のような」オブジェクトです。つまり、オブジェクトには長さがありますが、他の配列関数はありません。詳細およびこの回答については、developer.mozilla.org / en-US
length
プロパティを持つ任意のオブジェクトで機能するように定義されています。これにはarguments
オブジェクトが含まれます。これと、メソッドconcat
が呼び出された「配列」のコピーを返すことを知っていれば、次のarguments
ようにオブジェクトを実際の配列に簡単に変換できますvar args = [].concat.call(arguments)
。Array.prototype.concat.call
代わりに使用することを好む人もいますが、私はが好きで[]
、短くて甘いです!
[...arguments].join()
(ほとんどの)最近のブラウザーでは、次の構文で可変数の引数を受け入れることができます。
function my_log(...args) {
// args is an Array
console.log(args);
// You can pass this array as parameters to another function
console.log(...args);
}
ここに小さな例があります:
function foo(x, ...args) {
console.log(x, args, ...args, arguments);
}
foo('a', 'b', 'c', z='d')
=>
a
Array(3) [ "b", "c", "d" ]
b c d
Arguments
0: "a"
1: "b"
2: "c"
3: "d"
length: 4
ドキュメントとその他の例:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
別のオプションは、コンテキストオブジェクトで引数を渡すことです。
function load(context)
{
// do whatever with context.name, context.address, etc
}
このように使用します
load({name:'Ken',address:'secret',unused:true})
これには、名前付き引数をいくつでも追加できるという利点があり、関数は必要に応じてそれらを使用する(または使用しない)ことができます。
context
コードを使用して引数を作成し、使用する前に渡すことができるので、これも便利です。
私はケンの答えが最もダイナミックであることに同意し、さらに一歩進めたいと思います。異なる引数で複数回呼び出す関数の場合-私はケンのデザインを使用しますが、次にデフォルト値を追加します。
function load(context) {
var defaults = {
parameter1: defaultValue1,
parameter2: defaultValue2,
...
};
var context = extend(defaults, context);
// do stuff
}
このように、多くのパラメーターがあり、関数を呼び出すたびにパラメーターを設定する必要がない場合は、単にデフォルト以外を指定できます。拡張メソッドについては、jQueryの拡張メソッド($.extend()
)を使用するか、独自に作成するか、以下を使用できます。
function extend() {
for (var i = 1; i < arguments.length; i++)
for (var key in arguments[i])
if (arguments[i].hasOwnProperty(key))
arguments[0][key] = arguments[i][key];
return arguments[0];
}
これにより、コンテキストオブジェクトがデフォルトとマージされ、オブジェクトの未定義の値がデフォルトで入力されます。
_.defaults()
メソッドは、指定された引数とデフォルトの引数をマージする非常に優れた方法です。
Ramastが指摘したように、残りのパラメーター構文を使用することをお勧めします。
function (a, b, ...args) {}
... args引数の素敵なプロパティを追加したいだけです
- これは配列であり、引数のようなオブジェクトではありません。これにより、マップやソートなどの機能を直接適用できます。
- すべてのパラメーターが含まれているわけではなく、そこから渡されたパラメーターのみが含まれています。たとえば、この場合の関数(a、b、... args)には、args.lengthに対する引数3が含まれます。
すでに述べたように、 arguments
オブジェクトを使用して、可変数の関数パラメーターを取得ます。
同じ引数で別の関数を呼び出す場合は、を使用しますapply
。arguments
配列に変換することで、引数を追加または削除することもできます。たとえば、次の関数はコンソールにログインする前にテキストを挿入します。
log() {
let args = Array.prototype.slice.call(arguments);
args = ['MyObjectName', this.id_].concat(args);
console.log.apply(console, args);
}
名前付き引数のアプローチは有用で柔軟であることに一般的に同意しますが(順序を気にしない限り、引数が最も簡単です)、mbeasleyアプローチのコスト(デフォルトと拡張を使用)について懸念があります。これは、デフォルト値を取得するためにかかる非常に大きなコストです。最初に、デフォルトは関数内で定義されるため、すべての呼び出しでデフォルトが再設定されます。次に、||を使用すると、名前付きの値を簡単に読み取って、デフォルトを同時に設定できます。この情報を取得するために、別の新しいオブジェクトを作成してマージする必要はありません。
function load(context) {
var parameter1 = context.parameter1 || defaultValue1,
parameter2 = context.parameter2 || defaultValue2;
// do stuff
}
これは、ほぼ同じ量のコードです(多分少し多いかもしれません)が、実行時コストのほんの一部です。
(parameter1=context.parameter1)===undefined && (parameter1=defaultValue1)
またはコード量を減らすには、次のような小さなヘルパー関数function def(providedValue, default) {return providedValue !== undefined ? providedValue : defaultValue;} var parameter1 = def(context.parameter1, defaultValue1)
を使用します。ただし、私の主張はまだ残っています。すべての関数呼び出し用に追加のオブジェクトを作成し、いくつかのデフォルト値を設定するために高価なループを実行すると、非常に大きなオーバーヘッドになります。
@roufamaticはargumentsキーワードの使用を示し、@ Kenは使用法のオブジェクトの優れた例を示しましたが、私はこのインスタンスで何が起こっているかについて真に対処しておらず、将来の読者を混乱させたり、関数を明示的に述べていないので悪い習慣を植え付けたりする可能性があります/メソッドは、可変量の引数/パラメーターを取ることを目的としています。
function varyArg () {
return arguments[0] + arguments[1];
}
別の開発者があなたのコードを調べているとき、この関数がパラメータを取らないと非常に簡単に想定できます。特にその開発者がargumentsキーワードに精通していない場合。このため、スタイルガイドラインに従って一貫性を保つことをお勧めします。すべての例でGoogleを使用します。
同じ関数に可変パラメーターがあることを明示的に述べましょう:
function varyArg (var_args) {
return arguments[0] + arguments[1];
}
データマップの唯一の承認および検討されたベストプラクティスメソッドであるため、オブジェクトが必要になる場合があります。連想配列は眉をひそめ、推奨されません。
サイドノート: argumentsキーワードは、実際には数字をキーとして使用してオブジェクトを返します。プロトタイプの継承もオブジェクトファミリです。JSでの適切な配列の使用については、回答の最後を参照してください
この場合、これも明示的に述べることができます。注:この命名規則はGoogleでは提供していませんが、パラメーターの型の明示的な宣言の例です。これは、コードでより厳密な型付きパターンを作成する場合に重要です。
function varyArg (args_obj) {
return args_obj.name+" "+args_obj.weight;
}
varyArg({name: "Brian", weight: 150});
これは、関数およびプログラムのニーズによって異なります。たとえば、渡されたすべての引数にわたって反復プロセスに基づいて値を返すことを単に望んでいる場合、ほとんどの場合、引数キーワードを使用します。引数の定義とデータのマッピングが必要な場合は、オブジェクトメソッドが適しています。2つの例を見てみましょう。それで完了です。
function sumOfAll (var_args) {
return arguments.reduce(function(a, b) {
return a + b;
}, 0);
}
sumOfAll(1,2,3); // returns 6
function myObjArgs(args_obj) {
// MAKE SURE ARGUMENT IS AN OBJECT OR ELSE RETURN
if (typeof args_obj !== "object") {
return "Arguments passed must be in object form!";
}
return "Hello "+args_obj.name+" I see you're "+args_obj.age+" years old.";
}
myObjArgs({name: "Brian", age: 31}); // returns 'Hello Brian I see you're 31 years old
回答の上で述べたように、argumentsキーワードは実際にはオブジェクトを返します。このため、配列に使用するすべてのメソッドを呼び出す必要があります。この例:
Array.prototype.map.call(arguments, function (val, idx, arr) {});
これを回避するには、restパラメーターを使用します。
function varyArgArr (...var_args) {
return var_args.sort();
}
varyArgArr(5,1,3); // returns 1, 3, 5