jsの中でargments、caler、calee、appyの使い方は結びます.

5775 ワード

上記の概念を言及する前に、まずjavascriptの関数の暗黙的パラメータについて説明したいです.
Agments
オブジェクトは、実行中の関数とその関数を呼び出すパラメータを表します.
[function.]アーグメンント[n]パラメータfunction:オプション.現在実行中のFunctionオブジェクトの名前.n:オプション.Functionオブジェクトに渡す0からのパラメータ値インデックスです.Agmentsは関数コールを行う場合、指定されたパラメータの他に作成された隠しオブジェクトです.Agmentsは配列のようなアクセス特性と方式を持っているので、argments[n]によって対応する単一パラメータの値にアクセスでき、配列長属性lengthを持っているという配列のようなオブジェクトではない.また、argmentsオブジェクトは、関数宣言によって定義されたパラメータリストに限定されず、実際に関数に伝達されるパラメータを格納し、argmentsオブジェクトを明示的に作成することができません.アーグメンントオブジェクトは関数の開始時のみ使用できます.これらの性質を以下の例で詳しく説明します.
 
  
//arguments 。
function ArgTest(a, b){
   var i, s = "The ArgTest function expected ";
   var numargs = arguments.length;     // 。
   var expargs = ArgTest.length;       // 。
   if (expargs < 2)
      s += expargs + " argument. ";
   else
      s += expargs + " arguments. ";
   if (numargs < 2)
      s += numargs + " was passed.";
   else
      s += numargs + " were passed.";
   s += "

"
   for (i =0 ; i < numargs; i++){      // 。
   s += " Arg " + i + " = " + arguments[i] + "
";
   }
   return(s);                          // 。
}
ここには、アーグメンントが配列ではないことを示すコードが追加されています.
 
  
Array.prototype.selfvalue = 1;
alert(new Array().selfvalue);
function testAguments(){
    alert(arguments.selfvalue);
}
実行コードは、最初のalertが1を示しています.これは配列オブジェクトがselfvalue属性を持っていることを表しています.値は1です.関数testAggamentsを呼び出したときに、「undefined」と表示されていることが分かります.アーグメンツの属性ではなく、つまり、アーグメンツは配列オブジェクトではありません.
caler
関数の参照を返します.関数は現在の関数を呼び出します.functionName.caller functionNameオブジェクトは実行関数の名前です.説明は関数に対して、caler属性は関数実行時のみ定義されます.関数がトップレベルで呼び出された場合、calerに含まれるのはnullです.文字列コンテキストでcaler属性を使用すると、結果はfunctionName.toStringと同じで、つまり関数の逆コンパイルテキストが表示されます.以下の例では、caler属性の使い方を説明します.
 
  
// caller demo {
function callerDemo() {
    if (callerDemo.caller) {
        var a= callerDemo.caller.toString();
        alert(a);
    } else {
        alert("this is a top function");
    }
}
function handleCaller() {
    callerDemo();
}
calee
実行中のFunctionオブジェクト、すなわち指定されたFunctionオブジェクトの本文を返します.
[Function.]argments.caleeオプションfunctionパラメータは、現在実行中のFunctionオブジェクトの名前です.
なお、calee属性の初期値は、実行中のFunctionオブジェクトである.calee属性は、関数オブジェクト自体に対する参照を表し、匿名関数の再帰性または保証関数のパッケージ性、例えば、以下の例の再帰的計算1〜nの自然数の和を意味するargmentsオブジェクトのメンバである.この属性は、相関関数が実行中の場合にのみ使用できます.なお、length属性を持つcaleeは、この属性を検証するために使う場合があります.argments.lengthは実参長であり、argments.calee.lengthは形参長であり、これにより、呼び出し時の形参長が実参長と一致するかどうかを判断することができる.
 
  
//callee
function calleeDemo() {
    alert(arguments.callee);
}
//
function calleeLengthDemo(arg1, arg2) {
    if (arguments.length==arguments.callee.length) {
        window.alert(" !");
        return;
    } else {
        alert(" :" +arguments.length);
        alert(" : " +arguments.callee.length);
    }
}
//
var sum = function(n){
if (n <= 0)                       
return 0;
else
    return n +arguments.callee(n - 1)
}
一般的な再帰関数を比較:
 
  
var sum = function(n){
    if (n<=0)
  return 0;
 else
  return n + sum (n-1);
}
呼び出し時:alert(sum(100);
関数の内部にはsum自身への参照が含まれています.関数名は変数名だけで、関数の内部でsumを呼び出します.すなわちグローバル変数を呼び出すのに相当します.呼び出し自体をうまく表現できない場合、コールを使うのが良い方法です.
apply and call
それらの役割は、関数を別のオブジェクトに結びつけて実行することであり、両者はパラメータの定義の仕方だけで違いがあります.
apply(thisArg,argAray)call(thisArg[,arg 1,arg 2…])
つまり、すべての関数の内部のthisポインタは、他のオブジェクトとして機能を実行するための方法として、thisArgとして与えられます.
applyの説明は、argArayが有効な配列でないか、あるいはargmentsオブジェクトでない場合、TypeErrorを引き起こすことになります.argArayおよびthisArgのいずれかのパラメータが提供されていない場合、GlobalオブジェクトはthisArgとして使用され、どのパラメータも伝達されません.
callの例示的なcall方法は、関数のオブジェクトコンテキストを初期のコンテキストからthisArgによって指定された新しいオブジェクトに変更することができる.thisArgパラメータが提供されていない場合、GlobalオブジェクトはthisArgとして使用される.
関連技術:
callとappyを応用するもう一つのテクニックは中にあります.callとappyを別の関数(クラス)に適用した後、現在の関数(クラス)はもう一つの関数(クラス)の方法または属性を備えています.これは「継承」とも言えます.以下の例を参照してください
 
  
//
function base() {
    this.member = " dnnsun_Member";
    this.method = function() {
        window.alert(this.member);
    }
}
function extend() {
    base.call(this);
    window.alert(member);
    window.alert(this.method);
}
上記の例では、コールした後、extedはベースの方法と属性を継承することができます.
ちなみに、javascriptフレームワークprototypeでは、appyを使って定義タイプのパターンを作成します.
実は現代のサイズは以下の通りです.
 
  
var Class = {
create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
}
}
解析:コードから見ると、オブジェクトは一つの方法しか含まれていません.Createは関数、すなわちクラスを返します.しかし、これはまた、クラスのコンストラクタであり、initializeを呼び出すが、この方法はクラス作成時に定義される初期化関数である.このようなルートで、プロジェクトのクラス作成モードを実現できます.
例:
 
  
var vehicle=Class.create();
vehicle.prototype={
    initialize:function(type){
        this.type=type;
    }
    showSelf:function(){
        alert("this vehicle is "+ this.type);
    }
}

var moto=new vehicle("Moto");
moto.showSelf();