標籤:style blog color java 使用 io strong ar
this是物件導向語言中的一個重要概念,在JAVA,C#等大型語言中,this固定指向運行時的當前對象。但是在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) 輸出是 200px,可見當前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 輸出的卻是undefined,而不是hello,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這兩個方法:
call, apply作用就是借用別人的方法來調用,就像調用自己的一樣.從而改變了當前this的指向.
call(this, args1, args2, args3,…) //參數為個數
apply(this, [args1, args2, args3,…])//參數為數組
下面來看幾個簡單的例子:
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兩方法的調用與區別,下面,我們看看這兩個方法如何改變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,這種方式的運用,可以用於類比繼承,從而實現了代碼的重用。