前の言葉
JavaScript関数のパラメーターは、他のほとんどの言語の関数のパラメーターとは異なります。関数は、パラメーターが渡されるパラメーターの数も気にしません。また、渡されたパラメーターのデータ型を気にしたり、パラメーターを渡すことさえできません。
議論
JavaScriptの関数定義は、関数パラメーターのタイプを指定しておらず、関数呼び出しでは、渡されたパラメーター値のタイプチェックを実行しません。実際、JavaScript関数呼び出しは、着信する正式なパラメーターの数を確認しません。
関数add(x){return x+1;} console.log(add(1)); // 2console.log(add( '1')); // '11'console.log(add()); // nanconsole.log(add(1,2)); // 2同じ名前の正式なパラメーター
非ストリクトモードでは、同じ名前の正式なパラメーターが関数に表示され、表示される名前の最後の正式なパラメーターのみにアクセスできます
関数add(x、x、x){return x;} console.log(add(1,2,3)); // 3厳密なモードでは、同じ名前が構文エラーに関与しているときに構文エラーが発生します。
関数add(x、x、x){'strict'; return x;} console.log(add(1,2,3)); // syntaxerror:このコンテキストで許可されていない重複パラメーター名(パラメーターの数
実際の参照関数によって宣言された正式なパラメーターの指定数が小さい場合、残りの正式なパラメーターは未定義の値に設定されます
関数add(x、y){console.log(x、y); // 1未定義} add(1);頻繁にロジックまたは演算子を使用して、省略されたパラメーターの合理的なデフォルト値を設定する
関数add(x、y){y = y || 2; console.log(x、y); // 1 2} add(1);[注]実際、y ||を使用します2は厳密ではなく、明示的に偽の値を設定します(未定義、null、false、0、-0、 ''、nan)も同じ結果を得ます。したがって、実際のシナリオに基づいて合理的に設定する必要があります
多くの実際の議論がある場合、残りの実際の引数は直接取得することはできません。すぐに言及された引数オブジェクトを使用する必要があります。
JavaScriptのパラメーターは、配列で内部的に表されます。関数は常にこの配列を受信し、配列にどのパラメーターが含まれているかを気にしません。このパラメーター配列は、関数本文の引数オブジェクトを介してアクセスでき、それにより関数に渡される各パラメーターを取得できます。引数オブジェクトは配列のインスタンスではなく、四角いブラケット構文を使用してそのすべての要素にアクセスできる配列オブジェクトです。
関数add(x){console.log(arguments [0]、arguments [1]、arguments [2])// 1 2 3 Return x+1;} add(1,2,3);引数オブジェクトの長さ属性は実際のパラメーターの数を示し、関数の長さ属性は正式なパラメーターの数を示します
関数add(x、y){console.log(arguments.length)// 3turn x+1;} add(1,2,3); console.log(add.length); // 2正式なパラメーターは便利ですが、必要ではありません
function add(){return arguments [0] + arguments [1];} console.log(add(1,2)); // 3オブジェクトパラメーター
関数に3つ以上の正式なパラメーターが含まれている場合、関数の実際のパラメーターの正しい順序が呼び出されていることを覚えておくのは本当に頭痛の種です。
function arraycopy(/*array*/from、/*index*/form_start、/*array*/to、/*index*/to_start、/*integer*/length){// todo}パラメーターのペアの形でパラメーターを渡すため、パラメーターの順序は無関係になります。関数を定義するとき、実際のパラメーターで渡されたものは別のオブジェクトに書き込まれます。呼び出されたときにオブジェクトが渡されます。オブジェクトの名前/値のペアは、本当に必要な実際のパラメーターデータです。
function easycopy(args){arraycopy(args.from、args.form_start || 0、args.to、args.to_start || 0、args.length);} var a = [1,2,3,4]、b = []; easycopy({form:a、to:b、:4});同期
同じ形状に参加するフォームの実際のパラメーターの数が、引数オブジェクトの値と対応する正式なパラメーターの値が同期したままです
関数テスト(num1、num2){console.log(num1、arguments [0]); // 1 1arguments [0] = 2; console.log(num1、arguments [0]); // 2 2num1 = 10; console.log(num1、arguments [0]); // 10 10}テスト(1);[注]指定されたパラメーターと対応する引数オブジェクトの値は同じですが、それらは同じ名前空間ではありません。それらの名前空間は独立していますが、値は同期しています
ただし、厳密なモードでは、引数オブジェクトの値と正式なパラメーターの値は独立しています
関数テスト(num1、num2){'strict'; console.log(num1、arguments [0]); // 1 1arguments [0] = 2; console.log(num1、arguments [0]); // 1 2num1 = 10; console.log(num1、arguments [0]); // 10 2}テスト(1);正式なパラメーターに対応する実際のパラメーターがない場合、引数オブジェクトの値は正式なパラメーターの値に対応していません
関数テスト(num1、num2){console.log(num1、arguments [0]); // undefined、undefinednum1 = 10; arguments [0] = 5; console.log(num1、arguments [0]); // 10,5} test();内部プロパティ
【カリー】
引数オブジェクトには、Calleeと呼ばれるプロパティがあります。これは、引数オブジェクトを所有する関数へのポインターです。
以下は、古典的な要因関数です
関数係数(num){if(num <= 1){return 1;} else {return num* qualsial(num-1);}} console.log(factorial(5)); // 120ただし、上記の関数の実行は関数名と密接に結合されており、関数の分離を引数を使用して排除できます。
関数係数(num){if(num <= 1){return 1;} else {return num* arguments.callee(num-1);}} console.log(factorial(5)); // 120ただし、厳密なモードでは、このプロパティにアクセスするとタイプエラーエラーが発生します
関数因子(num){'strict'; if(num <= 1){return 1;} else {return num* arguments.callee(num-1);}} // typeerror: 'caller'、 'callee'、and 'arguments'プロパティは、ストリックモードの機能または引数の呼び出しのためのCalluments for themconsole(5);この時点で、名前付き関数式を使用できます
var因子= function fn(num){if(num <= 1){return 1;} else {return num*fn(num-1);}}; console.log(要因(5)); // 120【発信者】
実際、2つの発信者属性があります
【1】関数発信者
関数の発信者プロパティは、現在の関数を呼び出す関数への参照を保持します。現在の関数がグローバル範囲で呼び出された場合、その値はヌルです
function outer(){inner();} function inner(){console.log(inner.caller); // outer(){inner();}} outer(); function inner(){console.log(inner.caller); // null} inner();厳密なモードでは、このプロパティにアクセスするとタイプエラーエラーが発生します
function inenter(){'sprict'; // typeerror: 'caller' and 'arguments'は制限された関数プロパティであり、このContextconsole.log(inern.caller);} inner();} intern()でアクセスできません。【2】引数オブジェクト発信者
このプロパティは常に未定義です。このプロパティは、引用者のプロパティを引用と機能を区別するために定義されています。
関数内(x){console.log(arguments.caller); // undefined} inner(1);同様に、厳密なモードでは、このプロパティにアクセスするとタイプエラーエラーが発生します
関数内(x){'Strict'; // typeRror: 'caller'および 'arguments'は制限された関数プロパティであり、このcontextconsole.log(arguments.caller);} inner(1)でアクセスすることはできません。関数オーバーロード
JavaScript関数は、従来の意味のように過負荷を実装することはできません。他の言語では、これら2つの定義の署名(受け入れられたパラメーターのタイプと量)が異なる限り、関数に対して2つの定義を記述できます。
JavaScript関数には、パラメーターが0以上の値を含む配列で表されるため、署名はありません。関数の署名がなければ、実際の過負荷は不可能です
//後続の宣言は、以前の宣言関数をオーバーライドするaddsomeNumber(num){return num + 100;}関数addsomeNumber(num){return num + 200;} var result = addsomeNumber(100); // 300メソッドの過負荷は、渡された関数のパラメーターの種類と量をチェックし、異なる反応を行うことによってのみシミュレートできます。
function doadd(){if(arguments.length == 1){alert(arguments [0] + 10);} else if(arguments.length == 2){alert(arguments [0] + arguments [1]);}} doadd(10); // 20doadd(30,20); // 50パラメーターパス
JavaScriptのすべての関数は値で渡されます。つまり、関数の外側の値を関数内のパラメーターにコピーすることは、ある変数から別の変数に値をコピーすることと同じです
【1】基本的なタイプの値
プリミティブタイプの値をパラメーターに渡すと、渡された値はローカル変数(名前付きパラメーターまたは引数オブジェクトの要素)にコピーされます。
function addten(num){num += 10; return num;} var count = 20; var result = addten(count); console.log(count); // 20、no change console.log(result); // 30【2】参照タイプの値
参照タイプの値をパラメーターに渡すと、メモリ内のこの値のアドレスがローカル変数にコピーされるため、このローカル変数の変更は関数の外側に反映されます
function setname(obj){obj.name = 'test';} var person = new object(); setname(person); console.log(person.name); // 'test' '参照タイプの正式なパラメーターが関数内でオーバーライドされる場合、この変数はローカルオブジェクトを指します。このローカルオブジェクトは、機能が実行された直後に破壊されます
function setName(obj){obj.name = 'test'; console.log(person.name); // 'test'obj = new object(); obj.name =' white '; console.log(person.name); //' test '} var person = new object(); setName(); setName();上記は、編集者が紹介したJavaScript関数パラメーターの詳細な理解です(推奨)。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!