web-dev-qa-db-ja.com

Javascript:関数の「無限」パラメータ?

Chromeでは、次のようにconsole.logと入力すると、

console.log("A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter");

...エラーや警告なしで正しく印刷されます。さらにパラメータを追加しましたが、それでも正しく出力されます。

console.log("A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter");

どうすれば、そのような「無限の」パラメーター関数を持つことができますか?

38
user824294

関数は、受け取ったすべての引数を含むargumentsという配列のようなオブジェクトにアクセスできます

function print_my_arguments(/**/){
    var args = arguments;
    for(var i=0; i<args.length; i++){
        console.log(args[i]);
    }
};

また、applyメソッドを使用して、逆の変換(引数のリストを指定して関数を呼び出す)を実行できます。

// These are equivalent:
print_my_arguments(1,2,3);
print_my_arguments.apply(null, [1,2,3]);

// The first parameter to `apply` is the `this`.
// It is used when the function is a method.
foo.bar(1,2,3);
var f = foo.bar; f.apply(foo, [1,2,3]);

注意すべきいくつかの重要なポイント:

  1. argumentsは実際の配列ではなく、通常の配列メソッド(スライス、結合など)がありません。次の行で配列に変換できます。

    var args = Array.prototype.slice.call(arguments);
    
  2. 受け取った名前のない引数のみを配列に含める場合は、Sliceも役立ちます。

    function foo(first_arg, second_arg /**/){
        var variadic_args = Array.prototype.slice.call(arguments, 2);
    }
    
  3. すべてのブラウザが任意の数の関数パラメータを処理できるわけではありません。前回これをテストしたとき、Chrome and IEいくつかの200.000個の引数の後にスタックオーバーフローがありました。関数が任意の数の引数を受け取ることができる場合、代わりに、それらすべての引数を通常の配列にパックします。

  4. それら/**/私の例の引数リストに表示されるコメントは必須ではありません。これらは、可変部関数をマークし、通常の関数と区別するために使用する規約のコーディングにすぎません。

    // A quick glance would suggest that this function receives no
    // parameters but actually it is a variadic function that gets
    // its parameters via the `arguments` object.
    function foo(){
        console.log(arguments.length);
    }
    
55
hugomg

これを行う最新の方法は rest parameters を使用することです:

function printArguments(...args) {
  args.forEach((arg, index) => {
    console.log(`Argument ${index}:`, arg);
  });
}

printArguments('hello', true, new Date());

...args構文、すべてのパラメーターはargsという名前の配列に保存されます。

Internet Explorerを除き、すべてのブラウザーはこの機能を最新バージョンで出荷しています。

フィドル: https://jsfiddle.net/Lbf0stst/

8
Felix Edelmann

引数の配列を使用できます: jsfiddle.net/kUnJ2/

function foo() {
    for (var i = 0; i < arguments.length; i++) {
        document.body.innerHTML += arguments[i];
    }
}


foo("There ", "are ", "as ", "much ", "arguments ", "as ", "you ", "want.");
0
DynasteN