javascript関数が呼び出すオブジェクトと方法
3990 ワード
Javascript関数がどのように仕事を呼び出すかを本当に理解すれば、いくつかのバグの発生を避けることができます.
まず簡単な関数を作成します.この関数は以下で使います.この関数は現在のthisの値と二つの提供されたパラメータだけを返します.
問題が発生しました.thisの値はどうしてwindowになりましたか?簡単に分析します.
Javascriptには、グローバルオブジェクトがあります.それらはあなたのシナリオに散らばっているように見えます.各ラインのコードは、実はグローバルオブジェクトのコンテキストに書かれています.私たちの例では、そのmakeAray関数は緩いグローバル関数ではなく、グローバルオブジェクトの一つの方法です.ブラウザに戻ります.この環境では、全体のオブジェクトがwindowオブジェクトに写像されます.証明してみましょう.
これらすべては、私たちが以前にmakeArayを呼び出す方法と同じであり、
JavaScript関数呼び出しルール1:所有者オブジェクトを明確にしないで直接呼び出す関数で、myFunction()のように、thisの値がデフォルトのオブジェクト(ブラウザのウィンドウ)になります.
簡単なオブジェクトを作成します.makeAray関数をその一つの方法として使用します.json方式を使ってオブジェクトを宣言します.私達もこの方法を呼び出します.
これはイベント処理コードのbugの主なソースです.以下の例を見てください.
Javascript関数呼び出しルール3:関数を初期化関数として使用すると、MyFunction()のように、Javascriptの実行時にthisの値を新規作成のオブジェクトに指定します.
まず簡単な関数を作成します.この関数は以下で使います.この関数は現在のthisの値と二つの提供されたパラメータだけを返します.
function makeArray(arg1, arg2){
return [ this, arg1, arg2 ];
}
この関数を呼び出すのはとても簡単です.
makeArray('one', 'two');
戻り値:=>[window,one',two']問題が発生しました.thisの値はどうしてwindowになりましたか?簡単に分析します.
Javascriptには、グローバルオブジェクトがあります.それらはあなたのシナリオに散らばっているように見えます.各ラインのコードは、実はグローバルオブジェクトのコンテキストに書かれています.私たちの例では、そのmakeAray関数は緩いグローバル関数ではなく、グローバルオブジェクトの一つの方法です.ブラウザに戻ります.この環境では、全体のオブジェクトがwindowオブジェクトに写像されます.証明してみましょう.
alert( typeof window.makeArray);
戻り値:=>functionこれらすべては、私たちが以前にmakeArayを呼び出す方法と同じであり、
window.makeArray('one', 'two');
戻り値:=>[window,one',two']JavaScript関数呼び出しルール1:所有者オブジェクトを明確にしないで直接呼び出す関数で、myFunction()のように、thisの値がデフォルトのオブジェクト(ブラウザのウィンドウ)になります.
簡単なオブジェクトを作成します.makeAray関数をその一つの方法として使用します.json方式を使ってオブジェクトを宣言します.私達もこの方法を呼び出します.
var arrayMaker = {
someProperty: 'some value here',
make: makeArray
};
arrayMaker.make('one', 'two');
// :=> [ arrayMaker, 'one', 'two' ]
arrayMaker['make']('one', 'two');
// :=> [ arrayMaker, 'one', 'two' ]
thisの値は対象となりました.arrayMaker自体は元の関数の定義が変わっていないのか疑問に思うかもしれません.なぜwindowではないのですか?関数は対象です.それらを伝えたりコピーしたりすることができます.全体の関数はパラメータリストと関数体がコピーされているようです.そしてarrayMakerに割り当てられた属性makeは、arrayMakerのように定義されています.
var arrayMaker = {
someProperty: 'some value here',
make: function (arg1, arg2) {return [ this, arg1, arg2 ];}
};
JavaScript関数呼び出し規則2:一つの使い方で文法を呼び出すと、obj.myFunction()またはobj[myFunction]()のように、thisの値はobjとなります.これはイベント処理コードのbugの主なソースです.以下の例を見てください.
<br>function buttonClicked(){
<br>var text = (this === window) ? 'window' : this.id;
<br>alert( text );
<br>}
<br>var button1 = document.getElementById('btn1');
<br>var button2 = document.getElementById('btn2');
<br>button1.onclick = buttonClicked;
<br>// :=> btn1, ,this ( )
<br>button2.onclick = function(){buttonClicked();};
<br>// :=> window , buttonClicked() ( obj.buttonClicked().) , . , window.
<br>
Javascriptにはクラスがないことを知っています.また、任意のカスタムタイプには初期化関数が必要です.プロトタイプのオブジェクト(初期化関数としての属性)を使って、あなたのタイプを定義します.簡単なタイプを作成します.
function ArrayMaker(arg1, arg2) {
this.someProperty = 'whatever';
this.theArray = [ this, arg1, arg2 ];
}
//
ArrayMaker.prototype = {
someMethod: function () {
alert( 'someMethod called');
},
getArray: function () {
return this.theArray;
}
};
var am = new ArrayMaker( 'one', 'two' );
var other = new ArrayMaker( 'first', 'second' );
am.getArray();
// :=> [ am, 'one' , 'two' ]
注目すべきは、関数呼び出しの前に現れたnew演算子ではなく、関数は大域関数のように、そして私達が作成した属性は大域オブジェクト上に作成されます.そして、あなたはそうしたくないです.もう一つの話題は、あなたのコンストラクタの中で値が戻っていないので、new演算子を使うのを忘れたら、いくつかの変数がundefinedとして与えられます.このため、コンストラクタ関数は大文字で始まるのが良い習慣です.これは注意喚起として使えます.呼び出し時に前のnew演算子を忘れないようにしてください.Javascript関数呼び出しルール3:関数を初期化関数として使用すると、MyFunction()のように、Javascriptの実行時にthisの値を新規作成のオブジェクトに指定します.