これ、気をつけて!
9829 ワード
thisはオブジェクト向け言語の重要な概念で、JAVA、C#などの大規模な言語では、実行時の現在のオブジェクトを固定して指します.しかしJSではjavascriptのダイナミック性(解釈実行,もちろん簡単なプリコンパイルプロセスもある)のため,thisの指向は実行時に決定される.この特性は私たちに時々方向を乱すことができて、もしその動作原理を掌握したら、それは私たちにプログラミング上の自由と柔軟性を持ってきて、apply(call)方法を結合して、JSを異常に強大にすることができます.
デフォルトのthis:Javascriptでは、すべてのプロパティがwindowオブジェクトのすべてにデフォルト設定されているので、thisも例外ではありません.次の例を見て、まずウォーミングアップします.
このようにdemo()が実行されると、関数のthisはグローバルオブジェクトwindowを指します.次に、別の方法でdemoを呼び出して、thisがどこを指しているか見てみましょう.
demoがインスタンス化されると、thisは現在のインスタンス化されたオブジェクトを指すので、demoというクラスにはtxt変数がありますが、ここでtxtはクラスdemoのローカル変数に属し、ポインタ参照を定義していないので、demoがインスタンス化されると、thisはローカル変数txtを指していないので、txtを参照すると、未定義(undefined)と通知されます.
次に、バインドされたイベントのthisがどこを指しているかを見てみましょう.html:
Javascript:
divがクリックされると、alert(this.style.width)出力が200 pxであり、現在thisがonclick参照のオブジェクト(document.getElementById(「demo」)であることがわかります.
方法を変えて、thisが誰を指しているか見てみましょう.
ここで、divがalert(this.style.width)スクリプトをクリックしてthis.style.widthが空またはオブジェクトではないとエラーが発生します.なぜなら、現在thisはfunction(){}匿名関数を指しており、この匿名関数にはstyle.width属性は存在しないため、スクリプトはエラーを報告します.
上のイベントをバインドするthisに沿って、YUIのon方式でバインドされたthisの指向を話します.
inputがクリックされるとshowMsgは実行されますが、this.demo_txtはhelloではなくundefinedを出力します.tid!のここのthisはDemoオブジェクトではなくonバインドの関数のオブジェクトを指しているので、バインドされたオブジェクトにはdemo_は存在しません.txtプロパティ.出力が「hello,tid!」になるには、別の方法で呼び出さなければなりません.
このようにshowMsgのthisがDemoオブジェクトを指している場合は,我々が普段AJAXを用いてリクエストし,リクエストが成功した後にコールバックする方法のthisのように,ここでは説明を展開しない.
apply/call関数のthis:まずapply/callの2つの方法を簡単に紹介します:call、applyの役割は他の人の方法を借りて呼び出して、自分を呼び出すようにします.それによって現在のthisの指向.call(this,args 1,args 2,args 3,...)/パラメータは個数apply(this,[args 1,args 2,args 3,...])/パラメータは配列です
簡単な例をいくつか見てみましょう.
上記ではapply/callの2つのメソッドの呼び出しと区別について簡単に説明します.次に、この2つのメソッドがthis指向(this参照の伝達)をどのように変更するかを見てみましょう.
ここではsayMsgのthisがsayMsgTooを指していることが分かるが,この方式の運用は,シミュレーション継承に用いることができ,コードの再利用を実現した.
デフォルトのthis:Javascriptでは、すべてのプロパティがwindowオブジェクトのすべてにデフォルト設定されているので、thisも例外ではありません.次の例を見て、まずウォーミングアップします.
1 var txt = “Hello,Alex!”; 2 function demo(){ 3 var txt = “Hi,Alex!”; 4 alert(this.txt);// window.txt
5 } 6 demo();//output Hello,Alex!
このようにdemo()が実行されると、関数のthisはグローバルオブジェクトwindowを指します.次に、別の方法でdemoを呼び出して、thisがどこを指しているか見てみましょう.
1 var AA = new demo(); 2 AA();//output undefined
demoがインスタンス化されると、thisは現在のインスタンス化されたオブジェクトを指すので、demoというクラスにはtxt変数がありますが、ここでtxtはクラスdemoのローカル変数に属し、ポインタ参照を定義していないので、demoがインスタンス化されると、thisはローカル変数txtを指していないので、txtを参照すると、未定義(undefined)と通知されます.
次に、バインドされたイベントのthisがどこを指しているかを見てみましょう.html:
1 <input id=”demo” style=”width:200px; height:50px ;background:#000″ type=”button” value=”demo” />
Javascript:
1 function showMsg(){ 2 alert(this.style.width); 3 } 4 window.onload = function(){ 5 document.getElementById(“demo”).onclick = showMsg; 6 }
divがクリックされると、alert(this.style.width)出力が200 pxであり、現在thisがonclick参照のオブジェクト(document.getElementById(「demo」)であることがわかります.
方法を変えて、thisが誰を指しているか見てみましょう.
1 window.onload = function(){ 2 document.getElementById(“demo”).onclick = function(){showMsg()}; 3 }
ここで、divがalert(this.style.width)スクリプトをクリックしてthis.style.widthが空またはオブジェクトではないとエラーが発生します.なぜなら、現在thisはfunction(){}匿名関数を指しており、この匿名関数にはstyle.width属性は存在しないため、スクリプトはエラーを報告します.
上のイベントをバインドするthisに沿って、YUIのon方式でバインドされたthisの指向を話します.
1 YUI({combine: true}).use(‘io’, ‘until’, function (Y) { 2 var Demo = { 3 init : function(){ 4 Y.one(“#demo”).on(“click”,this.showMsg) 5 }, 6 demo_txt : “hello,tid!”, 7 showMsg : function(){ 8 alert(this.demo_txt); 9 } 10 } 11 }); 12 Demo.init();
inputがクリックされるとshowMsgは実行されますが、this.demo_txtはhelloではなくundefinedを出力します.tid!のここのthisはDemoオブジェクトではなくonバインドの関数のオブジェクトを指しているので、バインドされたオブジェクトにはdemo_は存在しません.txtプロパティ.出力が「hello,tid!」になるには、別の方法で呼び出さなければなりません.
1 init : function(){ 2 var $this = this; 3 Y.one(“#demo”).on(“click”,function(){$this.showMsg()}) 4 }
このようにshowMsgのthisがDemoオブジェクトを指している場合は,我々が普段AJAXを用いてリクエストし,リクエストが成功した後にコールバックする方法のthisのように,ここでは説明を展開しない.
apply/call関数のthis:まずapply/callの2つの方法を簡単に紹介します:call、applyの役割は他の人の方法を借りて呼び出して、自分を呼び出すようにします.それによって現在のthisの指向.call(this,args 1,args 2,args 3,...)/パラメータは個数apply(this,[args 1,args 2,args 3,...])/パラメータは配列です
簡単な例をいくつか見てみましょう.
1 function sayMsg(word1,word2){ 2 alert(word1 + word2); 3 } 4 function sayMsgToo(word1,word2){ 5 sayMsg.call(this,word1,word2); 6 //sayMsg.apply(this,[word1,word2]);
7 //sayMsg.apply(this,arguments);
8 } 9 sayMsgToo(“Hi”,”,Alex!”); //output Hi,Alex!
上記ではapply/callの2つのメソッドの呼び出しと区別について簡単に説明します.次に、この2つのメソッドがthis指向(this参照の伝達)をどのように変更するかを見てみましょう.
1 function sayMsg(){ 2 alert(this.word1 + this.word2); 3 } 4 function sayMsgToo(word1,word2){ 5 this.word1 = word1; 6 this.word2 = word2; 7 sayMsg.call(this); 8 //sayMsg.apply(this);
9 } 10 sayMsgToo(“Hi”,”,tid!”) //output Hi,tid!
ここではsayMsgのthisがsayMsgTooを指していることが分かるが,この方式の運用は,シミュレーション継承に用いることができ,コードの再利用を実現した.