関数のパラメータargments、現在のコンテキストthis、call apply
4759 ワード
関数のパラメータ
jsには様々な「疑似配列」があります.例えば、argmentsやdomに関するchildNodesなど、これらのオブジェクトにはlength属性がありますが、数字でインデックス要素を表示することもできます.しかし、それらはArayオブジェクトではなく、Objectオブジェクトです.これらのconstruct属性からはっきりと判断できます.
javascriptは関数のパラメータを扱う時、他のコンパイル型の言語と違っています.javascriptでは、インタプリタが関数に伝達するのは配列に似た内部値で、アーグメンツといいます.これは関数オブジェクトが生成される時に初期化されます.まず一例を通してこの不思議なargmentsを討論します.
もう一つの例を見ます
方法自体は関数ですが、方法の使用は制限されています.
各オブジェクトには0つ以上の属性が含まれており、属性は任意のタイプであってもよく、もちろんオブジェクトも含まれています.関数自体はオブジェクトですので、一つの関数をオブジェクトに入れることができます.この関数はオブジェクトの一つの方法になります.その後、この方法を用いると、オブジェクト名に「.」の操作子を利用して実現することができる.
メソッドの呼び出しにはオブジェクトのサポートが必要ですが、方法ではオブジェクトをどう取得しますか?thisthisキーワードは、この方法のオブジェクトを呼び出すという意味で、オブジェクトの呼び出し方法によって、thisキーワードがそのオブジェクトに向けられます.たとえば:
domObj.onclik=function(){
clickFun(this)/onclickは対象domObjの方法ですので、ここのthisはdomObjです.
)
javascriptでは、thisは、現在のコンテキスト、すなわち、使用者の引用(thisは、方法の使用者(オブジェクト)に対する参照を表している)を表している.thisの値は、関数がどのように宣言されているかではなく、どのように関数が呼び出されているかによって決まるのです.これは従来のオブジェクト指向言語とは違います.関数の文脈は変化することができますので、関数内のthisも変化することができます.関数はオブジェクトとしての方法もありますし、別のオブジェクトとしての方法もあります.つまり、thisは任意のオブジェクトとfunction要素を結合するときの概念だけで、関数自体は独立しています.関数のコンテキストは、Functionオブジェクトのcallまたはappy関数によって変更できます.
http://abruzzi.iteye.com/ブログの中の「javascriptカーネルシリーズ」
jsには様々な「疑似配列」があります.例えば、argmentsやdomに関するchildNodesなど、これらのオブジェクトにはlength属性がありますが、数字でインデックス要素を表示することもできます.しかし、それらはArayオブジェクトではなく、Objectオブジェクトです.これらのconstruct属性からはっきりと判断できます.
javascriptは関数のパラメータを扱う時、他のコンパイル型の言語と違っています.javascriptでは、インタプリタが関数に伝達するのは配列に似た内部値で、アーグメンツといいます.これは関数オブジェクトが生成される時に初期化されます.まず一例を通してこの不思議なargmentsを討論します.
function sum(){
var len = arguments.length
for(var i=0; i<len; i++){
alert(arguments[i]); // arguments
}
var result = 0;
for(var i=0; i<len; i++){
var current = arguments[i];
if(isNaN(current)){
throw new Error("not a number exception");
}else{
result += current;
}
}
return result;
}
sum(); // sum ,arguments ,arguments.length=0
sum(10, 20, 30, 40); // arguments.length=4 100
sum(4, 8, 15, 16, 23, 42);// arguments.length=6 108
sum("new");// arguments.length=1 Error: not a number exception
運転結果から、関数sumは明示的な形の参を定義していないが、任意の多くのパラメータに動的に伝達することができます.sum関数では、これらのパラメータをどのように参照しますか?ここではargmentsという対象を使う必要があります.もう一つの例を見ます
function f(x,y){
alert(x+" === "+y);
var len = arguments.length
for(var i=0; i<len; i++){
alert(arguments[i]); // arguments
}
}
f(1);
f(1,2);
f(1,2,3);
// : , arguments
// a , , a arguments[0] , ,
function change(a){
alert(a); // a gerry, alert gerry; alert undefined
arguments[0]='xiaoxiaozi'; // arguments[0]
alert(a); // , xiaoxiaozi
}
// :n*(n-1)*(n-2)*...*3*2*1
function factorial(n){
if(n == 1){
return 1;
}else{
return n * factorial(n - 1);
}
}
// :
function factorial(n){
return n==0 ? 1 : n * factorial(n-1);
}
// :
(function(x){
return x == 0 ? 1 : x * arguments.callee(x-1);
})(10);//3628800
,arguments.callee , 。caller
callee : Function , Function 。
caller : , 。
現在のコンテキストthis、call apply方法自体は関数ですが、方法の使用は制限されています.
各オブジェクトには0つ以上の属性が含まれており、属性は任意のタイプであってもよく、もちろんオブジェクトも含まれています.関数自体はオブジェクトですので、一つの関数をオブジェクトに入れることができます.この関数はオブジェクトの一つの方法になります.その後、この方法を用いると、オブジェクト名に「.」の操作子を利用して実現することができる.
メソッドの呼び出しにはオブジェクトのサポートが必要ですが、方法ではオブジェクトをどう取得しますか?thisthisキーワードは、この方法のオブジェクトを呼び出すという意味で、オブジェクトの呼び出し方法によって、thisキーワードがそのオブジェクトに向けられます.たとえば:
domObj.onclik=function(){
clickFun(this)/onclickは対象domObjの方法ですので、ここのthisはdomObjです.
)
javascriptでは、thisは、現在のコンテキスト、すなわち、使用者の引用(thisは、方法の使用者(オブジェクト)に対する参照を表している)を表している.thisの値は、関数がどのように宣言されているかではなく、どのように関数が呼び出されているかによって決まるのです.これは従来のオブジェクト指向言語とは違います.関数の文脈は変化することができますので、関数内のthisも変化することができます.関数はオブジェクトとしての方法もありますし、別のオブジェクトとしての方法もあります.つまり、thisは任意のオブジェクトとfunction要素を結合するときの概念だけで、関数自体は独立しています.関数のコンテキストは、Functionオブジェクトのcallまたはappy関数によって変更できます.
call apply Function , , this call apply , :
var name = "the name of window";// ,name
var jack = { // , jack
name : "jack",
age : 26
}
var gerry = { // , gerry
name : "gerry",
age : 25
}
function printName(){ //
return this.name;
}
// printName jack, this jack
alert(printName.call(jack));
// printName gerry, this gerry
alert(printName.call(gerry));
// printName window, this window, "the name of window"
alert(printName.call(window));
// , : window printName 。 window , window , 。 "the name of window"
printName();
// apply :
alert(printName.apply(jack));
alert(printName.apply(gerry));
call apply , ,apply , call , (,) :
setName.apply(jack, ["tom"]);
alert(printName.apply(jack)); // tom
setName.call(gerry, "gerry wang");
alert(printName.call(gerry)); // gerry wang
参考:http://abruzzi.iteye.com/ブログの中の「javascriptカーネルシリーズ」