引数と呼び出し先の属性を理解する

引数

  JavaScript の関数定義では関数パラメータの型が指定されておらず、関数呼び出しでは、受け取った実際のパラメータ値に対して型チェックが実行されません実際、JavaScript の関数呼び出しでは、渡されるパラメーターの数さえチェックされません。

function add(x){
return x+1;
}
console.log(add(1));//2
console.log(add('1'));//'11'
console.log(add());//NaN
console.log(add(1,2));//2

同名形参

非厳密モードでは、同じ名前のパラメータが関数内に出現でき、同じ名前の最後のパラメータのみにアクセスできます。

function add(x,x,x){
return x;
}
console.log(add(1,2,3));//3

  而在严格模式下,出现同名形参会抛出语法错误

function add(x,x,x){
'use strict';
return x;
}
console.log(add(1,2,3));//SyntaxError

パラメータの数

  実際の参照関数宣言で指定した仮引数の数が少ない場合、残りの仮引数は不定値に設定されます。

function add(x,y){
console.log(x,y);//1 undefined
}
add(1);

  常常使用逻辑或运算符给省略的参数设置一个合理的默认值

function add(x,y){
y = y || 2;
console.log(x,y);//1 2
}
add(1);

[注意] 実際には、 y || 2 の使用は厳密ではなく、明示的に false 値 (未定義、null、false、0、-0、''、NaN) を設定しても同じ結果が得られます。したがって、実際のシーンに応じて合理的に設定する必要があります。

  仮パラメータよりも実パラメータが多い場合、残りの実パラメータを直接取得することができず、言及する引数オブジェクトを使用する必要がある

  JavaScript のパラメータは内部的に配列で表されます。関数は、配列にどのパラメータが含まれているかに関係なく、常にこの配列を受け取ります。関数本体では、引数オブジェクトを介してこのパラメーター配列にアクセスし、関数に渡される各パラメーターを取得できます。引数オブジェクトは Array のインスタンスではなく、配列のようなオブジェクトであり、その各要素には角かっこ構文を使用してアクセスできます。

function add(x){
console.log(arguments[0],arguments[1],arguments[2])//1 2 3
return x+1;
}
add(1,2,3);

  arguments对象的length属性显示实参的个数,函数的length属性显示形参的个数
	
function add(x,y){
console.log(arguments.length)//3
return 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,length:4});

同期する

  仮パラメータと実パラメータの数が同じ場合、引数オブジェクトの値と対応する仮パラメータの値は同期されます。
function test(num1,num2){
console.log(num1,arguments[0]);//1 1
arguments[0] = 2;
console.log(num1,arguments[0]);//2 2
num1 = 10;
console.log(num1,arguments[0]);//10 10
}
test(1);

[注意] 名前付きパラメータは、対応する引数オブジェクトと同じ値を持ちますが、同じ名前空間にありません。名前空間は独立していますが、値は同期されます
  が、厳密モードでは、引数オブジェクトの値と仮パラメータの値は独立しています。
function test(num1,num2){
'use strict';
console.log(num1,arguments[0]);//1 1
arguments[0] = 2;
console.log(num1,arguments[0]);//1 2
num1 = 10;
console.log(num1,arguments[0]);//10 2
}
test(1);

  当形参并没有对应的实参时,arguments对象的值与形参的值并不对应

function test(num1,num2){
console.log(num1,arguments[0]);//undefined,undefined
num1 = 10;
arguments[0] = 5;
console.log(num1,arguments[0]);//10,5
}
test();

内部プロパティ

【着信者】

  引数オブジェクトには callee という属性があり、これは引数オブジェクトを所有する関数へのポインタです。

  これは古典的な階乗関数 (再帰的)です。

function factorial(num){
if(num <=1){
return 1;
}else{
return num* factorial(num-1);
}
} 
console.log(factorial(5));//120
ただし、上記の関数の実行は関数名と密接に結合されているため、arguments.callee を使用して関数の分離を排除できます。
function factorial(num){
if(num <=1){
return 1;
}else{
return num* arguments.callee(num-1);
}
} 
console.log(factorial(5));//120

  但在严格模式下,访问这个属性会抛出TypeError错误

function factorial(num){
'use strict';
if(num <=1){
return 1;
}else{
return num* arguments.callee(num-1);
}
} 
//TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
console.log(factorial(5));

この場合、名前付き関数式を使用できます。
var factorial = function fn(num){
if (num <=1){
return 1;
} else {
return num*fn(num-1);
}
};
console.log(factorial(5)); //120



おすすめ

転載: blog.csdn.net/qq_34986769/article/details/52174404