02 八月 2009 @ 5:15 下午 
很多人搞不懂Javascript的「this」這個關鍵字,或者是覺得懂,但是有些地方的this又覺得怪怪的。看過一些this的教學,我覺得都講得太複雜了,其實「this」只有一個重點而已。 this永遠指向「被執行時的作用域」 蝦毁??被執行?作用域??沒關係,試著把自己當作是編譯器,只要你不會在自己所撰寫的程式中迷路,其實this一點都不難區分。讓我們來看幾個例子:
 var t = this;console.log(t); //window
 function whatIsThis(){
     console.log(this); 
}
whatIsThis(); //window
 
變數t指向this,作用域在window底下,因此this指向window,這沒有問題,function whatIsThis裡頭印出的this指向誰?別會錯意囉,this永遠指向被「誰」呼叫,這個function是在window的作用域下被呼叫的,因此指向window,同理,我們來看下個例子:
 function wrapper(){
     whatIsThis();
 }
wrapper(); //window
 
什麼?我是透過wrapper這個function來呼叫whatIsThis的,為什麼還是window?請想想wrapper的作用域是誰?是 window,window呼叫wrapper,this還是指向window,作用域並沒有改變,這時呼叫whatIsThis當然作用域還是沒有改變,依然指向window。 接下來結合其他的型態:
 var arr = [this, 1, 2, function(){console.log(this)}];
 console.log(arr[0]); //window
 arr[3](); //arr
 
arr[0]指向window,原因是arr這個陣列被宣告時作用域是在window底下的,因此arr[0]是指向this。而arr[3]呢?當他被執行時,this被closure的方式被保存在function裡頭,因此呼叫arr[3]時,this指向他當時的作用域,也就是arr,看起來有點複雜,不過只要把自己想程式編譯器,問自己this何時被執行就好了。 Object跟Array一樣,其實大部分應該會更常在Object裡頭來使用this,我們來看一個比較實用的例子:
 var box = {
     length:100,
     width: 300,
     area: this.length* this.width
 };
 console.log(box.area);
 
看起來蠻合邏輯的一段程式,猜猜看,box.area是什麼?答案是NaN。Why?因為this根本就不是指向box,哪來的 this.length、this.width。剛說過this永遠指向「被執行的作用域」,box物件在宣告時,屬性volumn被指派時,this當然是指向window,所以這個邏輯是錯的。那怎辦?很多人遇到這個問題時,「那就不要使用this吧!」所以程式變成
 var box = {
     length:100,
     width: 300,
     area: box.length* box.width
 };
 console.log(box.area);
 
OK!box.area很正確的被計算出來了,但是這是個好辦法嗎?假如今天程式變成
 var box = {
     length:100,
     width: 300,
     area: box.length* box.width,
     volumn: box.length* box.width * box.height,
     height:50
};
 console.log('box.volumn='+box.volumn);
 
再猜猜看,box.volumn的值是什麼?答案是…..NaN,因為box在被宣告時,volumn屬性決定前尚未宣告height,導致 box.height變成undefined。「那就把height提前宣告就好啦?」等等,這樣真是不求甚解。這樣的需求用this的特性來取得是很直覺的事情,應該要想辦法搞定的。
 var box = {
     length:100,
     width: 300,
     getArea: function(){ return this.length* this.width},
     getVolumn: function(){ return this.length* this.width*this.height},
     height:50
 };
 console.log('box.volumn='+box.getVolumn());
 
如上,用getArea的function來動態取得box的長寬高,box.getVolumn function裡頭的this便是指向box這個物件,因為getVolumn被呼叫時,作用域就在box,所以this指向box。 this跟幾個重要型態的關係大概就是這樣,萬變不離其宗,在任何型態裡頭使用this都是照這個思維去走即可。下一篇會再介紹new Object之後的this以及與window事件交互作用之後的this。
Posted By: BLACKBING
Last Edit: 02 八月 2009 @ 05:25 下午

EmailPermalink
Tags


 

Responses to this post » (None)

 
Post a Comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


 Last 50 Posts
Change Theme...
  • Users » 17
  • Posts/Pages » 59
  • Comments » 28
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight

About Me



    No Child Pages.

留言板



    No Child Pages.

Album



    No Child Pages.