各JavaScript関数は、その範囲内で特別な変数 - 引数にアクセスできます。この変数には、関数に渡されたすべてのパラメーターのリストが含まれています。
引数オブジェクトは配列ではありません。構文的には配列と同じ場所がありますが、たとえば長さのプロパティがあります。しかし、それはarray.prototypeから継承されていません。実際、それはオブジェクトです。
したがって、プッシュ、ポップ、スライスなどの引数にいくつかの配列メソッドを使用することはできません。したがって、これらのメソッドを使用するには、実際の配列に変換する必要があります。
配列に変換します
次のコードは、引数オブジェクトのすべての要素を含む配列を返します。
array.prototype.slice.call(arguments);
コンバージョン速度は非常に遅いため、これは厳密なパフォーマンス要件を持つプログラムでは推奨されません。
パスパラメーター
引数オブジェクトをある関数から別の関数に渡すためのより推奨される方法を以下に示します。
コードコピーは次のとおりです。
function foo(){
bar.apply(null、arguments);
}
機能バー(A、B、C){
//ここで何かをします
}
別の巧妙な方法があります。これは、コールを使用して同時に適用するバンディングアウターメソッドをすばやく作成することです。
コードコピーは次のとおりです。
functionfoo(){}
foo.prototype.method = function(a、b、c){
console.log(this、a、b、c);
};
//「メソッド」のバウンドバージョンを作成する
//パラメーターを取ります:this、arg1、arg2 ... argn
foo.method = function(){
// result:foo.prototype.method.call(this、arg1、arg2 ... argn)
function.call.apply(foo.prototype.method、arguments);
};
関数パラメーターと引数属性の関係
引数オブジェクトは、独自のプロパティと関数パラメーターの両方に対してGetterおよびSetterメソッドを作成します。
したがって、関数の正式なパラメーターを変更すると、対応する引数オブジェクトのプロパティ値に影響し、その逆も同様です。
コードコピーは次のとおりです。
関数foo(a、b、c){
引数[0] = 2;
A; // 2
b = 4;
引数[1]; // 4
var d = c;
d = 9;
c; // 3
}
foo(1、2、3);
パフォーマンスの問題
引数は2つのケースのみで作成されず、1つは関数内のローカル変数として宣言され、もう1つは関数の正式なパラメーターとして使用されます。それ以外の場合、引数オブジェクトは常に作成されます。
GetterおよびSetterメソッドは常に引数オブジェクトの作成により作成されるため、引数を使用することはパフォーマンス自体にほとんど影響しません。
ただし、JavaScriptのパフォーマンスに深刻な影響を与える状況があります。これは、arguments.calleeを使用することです。
コードコピーは次のとおりです。
function foo(){
arguments.callee; //この関数オブジェクトで何かをします
arguments.callee.caller; //呼び出し関数オブジェクト
}
関数bigloop(){
for(var i = 0; i <100000; i ++){
foo(); //通常はインラインドされます...
}
}
上記のコードでは、FOO関数は、それ自体とその発信者を知る必要があるため、単純なインライン拡張機能ではなくなりました。これは、インライン拡張機能によってもたらされるパフォーマンスの改善を相殺するだけでなく、関数自体が特定の呼び出しの背景に依存する必要がある可能性があるため、関数のカプセル化を損なうこともできます。
したがって、arguments.calleeを使用しないようにすることをお勧めします。
上記は、JavaScript引数オブジェクトに関するすべてです。徹底的に知っていますか?簡単に言えば
引数は、関数のパラメーターオブジェクトを指します(実際の渡されたパラメーターを指します)
arguments.lengthは、関数のパラメーターオブジェクトの長さを指します。
引数[i]はi番目のパラメーターの値を指します(最初のパラメーターは0です)