これ、気をつけて!

9829 ワード

thisはオブジェクト向け言語の重要な概念で、JAVA、C#などの大規模な言語では、実行時の現在のオブジェクトを固定して指します.しかしJSではjavascriptのダイナミック性(解釈実行,もちろん簡単なプリコンパイルプロセスもある)のため,thisの指向は実行時に決定される.この特性は私たちに時々方向を乱すことができて、もしその動作原理を掌握したら、それは私たちにプログラミング上の自由と柔軟性を持ってきて、apply(call)方法を結合して、JSを異常に強大にすることができます.
デフォルトの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を指していることが分かるが,この方式の運用は,シミュレーション継承に用いることができ,コードの再利用を実現した.