argumentsとArray.prototype.slice.call : JavaScript


y@suさんからコメントでご指摘いただいた誤りを修正しました(2015.03.17)。

コード『JavaScript パターン』(Stoyan Stefanov)』にArray.prototype.slice.call(arguments)というコードがある。

すべての関数は自分へ渡された実引数をローカル変数argumentsとして持っている。
argumentsはlenghtプロパティを持ちarguments[0], … argument[N]でN番目の引数にアクセスできる配列に似たオブジェクト。
だが配列そのものではないので配列用のメソッドは定義されていない。
argumentsをArray.prototype.slice.call(arguments)で配列へ変換できる。

(function() {
    // argumentsは配列そのものではない。
    console.log(arguments instanceof Array); // false
    // 配列のメソッドは使えない
    // console.log(arguments.concat(['hoge'])); // TypeError: arguments.concat is not a function
    
    // 配列へ変換
    var arrArguments = Array.prototype.slice.call(arguments);
    // console.log(arguments instanceof Array); // true 本行のargumentsはarrArgumentsの誤りです(2015.03.17 )。
    console.log(arrArguments instanceof Array); // true
    // 配列のメソッドが使える
    console.log(arrArguments.concat(['hoge'])); // ["foo", "bar", "hoge"]
}('foo', 'bar'));

オブジェクトチェーンで短く書く。

(function() {
    console.log(Array.prototype.slice.call(arguments).concat(['hoge'])); // ["foo", "bar", "hoge"]    
}('foo', 'bar'));

配列インスタンスを使う。

(function() {
    console.log([].slice.call(arguments).concat(['hoge'])); // ["foo", "bar", "hoge"]    
}('foo', 'bar'));

sliceを別の使ったサンプル。

(function() {   
    console.log([].slice.call(arguments, 1)); // ["bar", "hoge"]
}('foo', 'bar', 'hoge'));
(function () {   
    console.log([].slice.call(arguments, 1, 3));// ["bar", "hoge"]
}('foo', 'bar', 'hoge'));

» Array slice method – JavaScript | MDN
» jsFiddle

コメント


  1. 最初のコードの9ステップ目ですが、
    console.log(arguments instanceof Array)
    ではなく、
    console.log(arrArguments instanceof Array)
    の間違いでは?

    コメント by y@su — 2015-03-16 @ 2:39 PM

  2. y@suさん

    間違いを教えていただきありがとうございます。
    修正をしました。

    コメント by findxfine — 2015-03-17 @ 4:28 PM

コメントの投稿

改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。