web-dev-qa-db-ja.com

JavaScriptで "arguments"オブジェクトを配列に変換する方法を教えてください。

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

単純なforループを使用して、argumentsオブジェクトから新しい配列を簡単に作成できます。たとえば、この関数は引数をソートします。

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

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

416
Andrew Coleson

レストパラメーターを使用するES6

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

残りのパラメーター

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

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

link で読むことができるように

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

...構文に興味がある場合は、Spread Operatorと呼ばれます。詳細は here を参照してください。

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.fromは、単純に配列のようなオブジェクトまたは反復可能なオブジェクトを配列インスタンスに変換します。



ES5

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

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

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

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

したがって、sliceは、lengthプロパティを持つものすべてで機能しますが、これはargumentsが便利です。


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

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

ただし、以前のバージョンはより明示的であると感じる傾向があるため、代わりにそれを使用したいと思います。配列リテラル表記を乱用すると、ハック感があり、奇妙に見えます。

701

を参照する価値があります。このBluebirdは、関数を最適化できるようにargumentsオブジェクトを配列に管理する方法を示すライブラリwikiページ を約束します V8 JavaScriptエンジンの下で

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

このメソッドはvar args = [].slice.call(arguments);のために使われています。作者はまた、ビルドステップがどのように冗長性を減らすのに役立つことができるかを示します。

38
jbmusso
function sortArgs(){ return [].slice.call(arguments).sort() }

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

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

[].sort.call({0:1, 1:0, length:2}) // => ({0:0, 1:1, length:2})
28
matyr

つかいます:

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();
}

バージョンを移動する(遅くなりますが、小さいサイズは速くなります)。

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();
}

もしあなたがjQueryを使っているなら、私の意見では覚えておくのが以下のほうがずっと簡単です。

function sortArgs(){
  return $.makeArray(arguments).sort();
}
9
brad

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 を使用してください。

これはベンチマークです 引数を配列に変換するいくつかの方法の。

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

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(); }
5
Gheljenor

Lodash:

var args = _.toArray(arguments);

実際には:

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

生成されます:

[2,3]
4
Zane Hooper

Array.from() を使用します。これは(argumentsなどの)配列のようなオブジェクトを引数として取り、それを配列に変換します。

(function() {
  console.log(Array.from(arguments));
}(1, 2, 3));

IE 11のような古いブラウザでは動作しませんので、これらのブラウザをサポートしたい場合は Babel を使用してください。

ECMAScript 6 スプレッド演算子 を使用することをお勧めします。これは末尾のパラメータを配列にバインドします。このソリューションではargumentsオブジェクトに触れる必要がなくなり、コードは単純化されます。この解決策のマイナス面は、ほとんどのブラウザで動作しないことですので、代わりにBabelなどのJSコンパイラを使用する必要があります。内部でBabelは、argumentsをforループを含む配列に変換します。

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

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

function sortArgs() {
    var args = Array.prototype.slice.call(arguments);
    return args.sort();
}
4
jjbskir
function sortArg(){
var args = Array.from(arguments); return args.sort();
}
 function sortArg(){
    var args = Array.from(arguments); 
    return args.sort();
    }
 
 console.log(sortArg('a', 'b', 1, 2, '34', 88, 20, '19', 39, 'd', 'z', 'ak', 'bu', 90));
3
Abk

もう一つの答え。

黒魔術呪文を使う:

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

Firefox、Chrome、Node.js、IE11は問題ありません。

Object.setPrototypeOf() を使ってみてください

説明:prototypeargumentsArray.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()

説明:オブジェクトを作成し、argumentsの各索引でobjectのプロパティーをitemsに設定してください。作成したオブジェクトのprototypeArray.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]]]))
1
guest271314

任意の引数でそれを行うために再利用可能な関数を作成することができます、最も簡単なものはこのようなものです:

function sortArgs() {
  return [...arguments].sort();
}

sortArgs('ALi', 'reza', 1, 2, 'a'); //[1, 2, "a", "ALi", "reza"];

スプレッド構文はES6以上で使用できます。

ただし、ES5以下と互換性のあるものを使用する場合は、Array.prototype.slice.callを使用できます。そのため、コードは次のようになります。

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

sortArgs('ALi', 'reza', 1, 2, 'a'); //[1, 2, "a", "ALi", "reza"];

これを行うには他にもいくつかの方法があります。例えば、Array.fromを使用するか、argumentsをループ処理して新しい配列に割り当てる...

0
Alireza
 function x(){
   var rest = [...arguments]; console.log(rest);return     
   rest.constructor;
 };
 x(1,2,3)

簡単な破壊手法を試してみました

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

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

Argumentsオブジェクトは関数本体の中でのみ利用可能です。 Argumentsオブジェクトは配列のようにインデックスを付けることができますが、配列ではありません。長さ以外の配列プロパティはありません。

// function arguments length 5
function properties(a,b,c,d,e){
var function_name= arguments.callee.name
var arguments_length= arguments.length;
var properties_length=  properties.length; 
var function_from= properties.caller.name;
console.log('I am the function name: '+ function_name);
console.log('I am the function length, I am function spacific: '+ properties_length); 
console.log('I am the arguments length, I am context/excution spacific: '+ arguments_length);
console.log('I am being called From: '+  function_from );
}

// arguments 3
function parent(){
properties(1,2,3);
}

//arguments length 3 because execution spacific
parent();

あなたはこの例で見ることができるようにそれは配列のようにインデックスを付けることができますが:

function add(){

var sum=0;

for(var i=0; i< arguments.length;i++){

sum = sum + arguments[i];

}

return sum;

}

console.log(add(1,2,3));

ただし、Argumentsオブジェクトは配列ではなく、length以外のプロパティはありません。

Argumentsオブジェクトを配列に変換できます。この時点で、Argumentsオブジェクトにアクセスできます。

関数本体内のargumentsオブジェクトにアクセスする方法はたくさんあります。

  1. array.prototoype.slice.callメソッドを呼び出すことができます。

Array.prototype.slice.call(引数)

function giveMeArgs(arg1,arg2){

var args = Array.prototype.slice.call(arguments);
return args
}

console.log( giveMeArgs(1,2));
  1. あなたは配列リテラルを使うことができます

[] .slice.call(引数).

function giveMeArgs(arg1,arg2){

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

return args;

}

console.log( giveMeArgs(1,2) );
  1. あなたは休憩を使用することができます...
function giveMeArgs(...args){

return args;

}

console.log(giveMeArgs(1,2))
  1. あなたはスプレッドを使用することができます[...]
function giveMeArgs(){

var args = [...arguments];
return args;

}

console.log(giveMeArgs(1,2));
  1. あなたはArray.from()を使うことができます
function giveMeArgs(){

var args = Array.from(arguments);

return args;

}

console.log(giveMeArgs(1,2));
0
Rick

これは、簡潔で簡潔な解決策です。

function argsToArray() {
  return Object.values(arguments);
}

// example usage
console.log(
  argsToArray(1, 2, 3, 4, 5)
  .map(arg => arg*11)
);

Object.values( ) はオブジェクトの値を配列として返します、そしてargumentsname__はオブジェクトなので、それは基本的にargumentsname__を配列に変換します、それでmapname__、forEachname__のような配列の全てのヘルパー関数を提供します。 、filtername__など.

0

Restパラメータはうまくいきますが、何らかの理由でargumentsを使い続けたい場合は、次の点を考慮してください。

function sortArgs() {
  return [...arguments].sort()
}

[...arguments]Array.from(arguments)の一種の代替手段と見なすことができ、これも完璧に機能します。

ES7の代替手段は配列内包表記です。

[for (i of arguments) i].sort()

ソートの前に引数を処理またはフィルタリングしたい場合は、これが最も簡単です。

[for (i of arguments) if (i % 2) Math.log(i)].sort()
0
user663031

Benshmarck 3メソッド:

function test()
{
  console.log(arguments.length + ' Argument(s)');

  var i = 0;
  var loop = 1000000;
  var t = Date.now();
  while(i < loop)
  {
      Array.prototype.slice.call(arguments, 0); 
      i++;
  }
  console.log(Date.now() - t);


  i = 0,
  t = Date.now();
  while(i < loop)
  {
      Array.apply(null, arguments);
      i++;
  }
  console.log(Date.now() - t);

  i = 0,
  t = Date.now();
  while(i < loop)
  {
      arguments.length == 1 ? [arguments[0]] : Array.apply(null, arguments);
      i++;
  }
  console.log(Date.now() - t);
}

test();
test(42);
test(42, 44);
test(42, 44, 88, 64, 10, 64, 700, 15615156, 4654, 9);
test(42, 'truc', 44, '47', 454, 88, 64, '@ehuehe', 10, 64, 700, 15615156, 4654, 9,97,4,94,56,8,456,156,1,456,867,5,152489,74,5,48479,89,897,894,894,8989,489,489,4,489,488989,498498);

結果?

0 Argument(s)
256
329
332
1 Argument(s)
307
418
4
2 Argument(s)
375
364
367
10 Argument(s)
962
601
604
40 Argument(s)
3095
1264
1260

楽しい !

0
Matrix