453

JavaScriptのargumentsオブジェクトは奇妙な点です。ほとんどの場合、オブジェクトは配列のように機能しますが、実際には配列オブジェクトではありません。それは実際にはまったく別のものであるため、、 、、Array.prototypeなどの便利な機能はありません。forEachsortfiltermap

単純な for ループを使用して、引数オブジェクトから新しい配列を構築するのは自明のことです。たとえば、次の関数は引数をソートします。

function sortArgs() {
    var args = [];
    for (var i = 0; i < arguments.length; i++)
        args[i] = arguments[i];
    return args.sort();
}

しかし、非常に便利な JavaScript 配列関数にアクセスするためだけにこれを行うのは、かなり残念なことです。標準ライブラリを使用してそれを行う組み込みの方法はありますか?

4

21 に答える 21

753

残りのパラメーターを使用する ES6

ES6 を使用できる場合は、次を使用できます。

レスト パラメータ

function sortArgs(...args) {
  return args.sort(function (a, b) { return a - b; });
}

document.body.innerHTML = sortArgs(12, 4, 6, 8).toString();

リンク先で読めるように

残りのパラメーター構文を使用すると、不特定の数の引数を配列として表すことができます。

構文に興味がある場合は、 Spread Operator...と呼ばれ、ここで詳細を読むことができます。

Array.from() を使用する ES6

Array.from の使用:

function sortArgs() {
  return Array.from(arguments).sort(function (a, b) { return a - b; });
}

document.body.innerHTML = sortArgs(12, 4, 6, 8).toString();

Array.fromArray-like または Iterable オブジェクトを Array インスタンスに変換するだけです。



ES5

実際には、引数オブジェクトでArrayslice関数を使用するだけで、標準の JavaScript 配列に変換されます。Array のプロトタイプを介して手動で参照する必要があります。

function sortArgs() {
    var args = Array.prototype.slice.call(arguments);
    return args.sort();
}

なぜこれが機能するのですか?さて、これはECMAScript 5 ドキュメント自体からの抜粋です:

:slice関数は意図的に汎用的です。この値が Array オブジェクトである必要はありません。したがって、メソッドとして使用するために他の種類のオブジェクトに転送できます。slice関数をホスト オブジェクトに正常に適用できるかどうかは、実装に依存します。

したがって、便利なことに、プロパティsliceを持つものすべてに機能します。lengtharguments


Array.prototype.sliceが多すぎる場合は、配列リテラルを使用して少し省略できます。

var args = [].slice.call(arguments);

ただし、以前のバージョンの方が露骨であると感じる傾向があるので、代わりに使用したいと思います。配列リテラル表記を悪用すると、ハックに感じられ、奇妙に見えます。

于 2009-06-07T00:10:20.227 に答える
29
function sortArgs(){ return [].slice.call(arguments).sort() }

// Returns the arguments object itself
function sortArgs(){ return [].sort.call(arguments) }

一部の配列メソッドは、ターゲット オブジェクトが実際の配列である必要がないように意図的に作成されています。それらは、ターゲットが長さとインデックス (ゼロ以上の整数でなければならない)という名前のプロパティを持つことのみを必要とします。

[].sort.call({0:1, 1:0, length:2}) // => ({0:0, 1:1, length:2})
于 2009-06-09T18:29:38.460 に答える
12

使用する:

function sortArguments() {
  return arguments.length === 1 ? [arguments[0]] :
                 Array.apply(null, arguments).sort();
}

Array(arg1, arg2, ...)戻り値[arg1, arg2, ...]

Array(str1)戻り値[str1]

Array(num1)num1要素を持つ配列を返します

引数の数を確認する必要があります!

Array.sliceバージョン (遅い):

function sortArguments() {
  return Array.prototype.slice.call(arguments).sort();
}

Array.pushバージョン (スライスより遅い、速い):

function sortArguments() {
  var args = [];
  Array.prototype.push.apply(args, arguments);
  return args.sort();
}

Move バージョン (遅いですが、サイズが小さいほど高速です):

function sortArguments() {
  var args = [];
  for (var i = 0; i < arguments.length; ++i)
    args[i] = arguments[i];
  return args.sort();
}

Array.concatバージョン (最も遅い):

function sortArguments() {
  return Array.prototype.concat.apply([], arguments).sort();
}
于 2013-10-27T14:39:14.820 に答える
9

jQuery を使用している場合は、次のようにすると覚えやすくなります。

function sortArgs(){
  return $.makeArray(arguments).sort();
}
于 2009-06-07T00:19:43.217 に答える
9

ECMAScript 6 では、 のような醜いハックを使用する必要はありませんArray.prototype.slice()代わりにスプレッド構文 ( ...)を使用できます。

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

奇妙に見えるかもしれませんが、かなり単純です。' 要素を抽出argumentsして配列に戻すだけです。それでも理解できない場合は、次の例を参照してください。

console.log([1, ...[2, 3], 4]);
console.log([...[1, 2, 3]]);
console.log([...[...[...[1]]]]);

IE 11 などの一部の古いブラウザーでは機能しないことに注意してください。これらのブラウザーをサポートする場合は、Babelを使用する必要があります。

于 2016-01-24T17:04:18.273 に答える
5

これは、引数を配列に変換するいくつかのメソッドのベンチマークです。

私にとって、少量の引数に対する最良の解決策は次のとおりです。

function sortArgs (){
  var q = [];
  for (var k = 0, l = arguments.length; k < l; k++){
    q[k] = arguments[k];
  }
  return q.sort();
}

その他の場合:

function sortArgs (){ return Array.apply(null, arguments).sort(); }
于 2013-07-03T09:05:18.823 に答える
4

末尾のパラメーターを配列にバインドするECMAScript 6スプレッド オペレーターを使用することをお勧めします。このソリューションを使用すると、オブジェクトに触れる必要がなくなりarguments、コードが簡素化されます。このソリューションの欠点は、ほとんどのブラウザーで機能しないことです。代わりに、Babel などの JS コンパイラーを使用する必要があります。内部では、Babelargumentsは for ループを使用して配列に変換されます。

function sortArgs(...args) {
  return args.sort();
}

ECMAScript 6 を使用できない場合は、@Jonathan Fingland などの他の回答を確認することをお勧めします。

function sortArgs() {
    var args = Array.prototype.slice.call(arguments);
    return args.sort();
}
于 2016-01-25T21:51:50.733 に答える
4

ロダッシュ:

var args = _.toArray(arguments);

実際に:

(function(){ console.log(_.toArray(arguments).splice(1)); })(1, 2, 3)

生成:

[2,3]
于 2016-10-04T23:41:17.053 に答える
1

使ってみてObject.setPrototypeOf()

説明:prototypeのセットargumentsArray.prototype

function toArray() {
  return Object.setPrototypeOf(arguments, Array.prototype)
} 

console.log(toArray("abc", 123, {def:456}, [0,[7,[14]]]))


説明: の各インデックスをarguments取得し、配列 の対応​​するインデックスにアイテムを配置します。

代わりに使用できますArray.prototype.map()

function toArray() {
  return [].map.call(arguments, (_,k,a) => a[k])
} 

console.log(toArray("abc", 123, {def:456}, [0,[7,[14]]]))


説明: の各インデックスをarguments取得し、配列 の対応​​するインデックスにアイテムを配置します。

for..ofループ

function toArray() {
 let arr = []; for (let prop of arguments) arr.push(prop); return arr
} 

console.log(toArray("abc", 123, {def:456}, [0,[7,[14]]]))


またObject.create()

説明: オブジェクトを作成し、オブジェクトのプロパティを の各インデックスの項目に設定しますargumentsprototype作成されたオブジェクトのセットArray.prototype

function toArray() {
  var obj = {};
  for (var prop in arguments) {
    obj[prop] = {
      value: arguments[prop],
      writable: true,
      enumerable: true,
      configurable: true
    }
  } 
  return Object.create(Array.prototype, obj);
}

console.log(toArray("abc", 123, {def: 456}, [0, [7, [14]]]))

于 2016-01-30T02:11:20.093 に答える
0
 function x(){
   var rest = [...arguments]; console.log(rest);return     
   rest.constructor;
 };
 x(1,2,3)

簡単な破壊術をやってみた

于 2016-07-09T18:17:39.543 に答える
0

function sortArgs(...args) {
  return args.sort(function (a, b) { return a - b; });
}

document.body.innerHTML = sortArgs(1, 2, 3, 4).toString();

于 2016-01-29T05:47:03.927 に答える