プロが教えるわが家の防犯対策術!

Array.prototype.slice.call(arguments);
と記述することで、配列ではないが、配列のような働きをするargumentsオブジェクトが持つ実引数を配列にすることができます。
Array.prototypeのsliceメソッドは、this参照を配列に変換する能力を持つそうです。sliceメソッドのあとでチェーンされているcallは、
レシーバオブジェクトのthis参照を第一引数、ここではargumentsオブジェクトにすることができます。

ここで質問ですが、なぜArray.prototype内に存在するthis参照をargumentsオブジェクトにすることでsliceメソッドなどが使えるようになるのでしょうか。
argumentsオブジェクトの__proto__がArray.prototypeになるとのことですが、Array.prototypeのthis参照をargumentsオブジェクトにすることと、個人的に繋がらず
ピンと来ません。

A 回答 (2件)

こんにちは


疑問点をよく把握できていませんが・・・

単純にcall関数がそのような仕様になっているからと考えるのではダメでしょうか?
NodeListなどのようにsliceをメソッドとして持っていないオブジェクトで、sliceメソッドを利用したい場合に、call関数を介することでArray.prototype.sliceメソッドを適用させるといった感じ。
https://developer.mozilla.org/ja/docs/Web/JavaSc …
    • good
    • 0

関数 slice は「意図的に汎用的」です。



関数内で使用する this に対して、以下の操作が可能ならば、
* this[index] の読み取り
* this.length の読み取り

this が配列オブジェクトだろうが、
「配列のようなオブジェクト」だろうが、
問題なく処理できてしまいます。

当然 arguments はこの二つの操作を備えていますので、
call によって this を挿げ替えれば slice が使えてしまいます。

以下サンプルです

function slice() {
_ var x = [], n = this.length;
_ for (var i=0; i<n; i++) x.push(this[i]);
_ return x;
}
var 配列オブジェクト1 = slice.call(配列オブジェクト);
var 配列オブジェクト2 = slice.call(配列のようなオブジェクト);


余談ではありますが、

call に __proto__ を変更する機能はありません。
対象の関数に対して、関数スコープ内の変数 this を挿げ替えるだけです。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!