標籤:
在我的職業生涯中,很早就已經開始使用JavaScript進行項目開發了。但是一直都是把重心放在了後端開發方面,前端方面鮮有涉及。所以造成的一個現象就是:目前的前端知識水平,應付一般的項目已然是足夠的,但是火候尚缺,沒有深入的進行研究,以至於總是談論起來就發現自己半瓶子哐當的水平。為瞭解決這種尷尬的局面,決心潛心研究一段時間JavaScript,以下知識為本人學習過程中的總結,雖然以本人水平可能招致貽笑大方之果,但是更盼拋磚引玉之實。
在JavaScript中,我們調用一個普通的方法,可以通過如下的方式來進行:
//全域公用調用方式function greetingMorning() { alert("Hello Morning!"); } greetingMorning(); //局部調用方式var greetingWorld =function() { alert("Hello World!"); } greetingWorld(); //自調用方式(function(){ alert("Hello ChaoYang!"); })();
那麼上面就是一般的三種調用方式,前兩種都會在window對象上面進行附加,不同之處就在於,第一種是直接利用function進行聲明方式,屬於公用調用方式;第二種是利用var關鍵字進行申明的方式調用。也就是說,第一種申明方式所申明的函數,無論在函數體之前或之後調用,都沒問題。而第二種申明方式所申明的函數,只能在函數體之後調用:
//正確,可以這麼調用greetingMorning(); function greetingMorning() { alert("Hello Morning!"); } //錯誤,提示找不到方法greetingWorld(); var greetingWorld =function() { alert("Hello World!"); }
在這裡,我們需要注意的第一個坑就是局部變數加不加var關鍵字的問題:
function greetingLucy() { name ="lucy"; alert("Hello "+name); } greetingLucy(); alert(name);
這裡我們的執行結果,第一次會輸出: Hello lucy, 第二次會輸出: lucy。 這很奇怪,為什麼name我寫到了方法裡面,按理來說已經是局部變數了,為什麼還是會輸出結果呢?其實在JavaScript中,在方法體內,如果不加var關鍵字的話,會將此變數預設為全域變數。這也是為什麼會輸出結果的原因了。
那麼知道了函數執行的一般方法,那麼我們來看函數的執行的特殊方法。
如上所述,我們直接利用 (); 的方式可以出發函數的立即執行。但是這種執行,其實在大多數情況下是無法改變this關鍵字的範圍的,由於this預設指向的就是已經執行個體化過的window對象,所以很多時候當我們需要更改this的範圍的時候,我們就不得不引入 apply, call 關鍵字 以及 bind 關鍵字。 我們先來講解他們的基本用法。
首先,對於apply方法:
//不帶參數,我們apply了this,可以看出我們改變了this的範圍 //從原本的window對象,指向了greetingLucyfunction greetingLucy() { var name ="lucy"; alert("Hello "+name); } greetingLucy.apply(this); //帶兩個參數function greeting(name, age) { alert("Hello "+ name +""+ age +" !"); } greeting.apply(this,["lucy",23]);
可以看出,使用apply的時候,其中第一個參數一定要指向需要應用的對象,之後的多個參數需要寫成數組的方式。
再來看看call方法:
function greetingLucy() { var name ="lucy"; alert("Hello "+name); } greetingLucy.call(this); function greeting(name,age) { alert("Hello "+ name +""+ age +" !"); } greeting.call(this,"lucy",25);
可以看出,使用call的時候,第一個參數也是需要指向被調用的對象,之後的多個參數可以直接寫就行。
從這裡我們可以看出,apply和call都會改變this的範圍,至於更詳細的資訊,我會放到第二節去講解。
下面我們來看看bind方法。
var color ="red"; var obj = {color:"blue"}; function sayColor(){ alert(this.color); } var nw = sayColor.bind(obj);//執行nw();
這裡會輸出什麼呢? 這裡會輸出“blue”。那為什麼不會輸出red呢? 其實在這裡,this關鍵字有個很重要的特點,那就是: 誰調用我,我指向誰。由於bind方法的調用,會導致this指向的改變,從window對象變成了指向obj對象。所以這裡會拿obj對象中的color來執行。
從上面的例子我們也可以看出,bind方法不會導致函數的立即執行,需要觸發才可以執行。
為什麼bind不會立即執行呢? 我們可以執行 alert(nw)看出返回給我們的結果:
function bound sayColor(){[native code]}
這說明bind以後返回的nw對象,就是一個函數,並且還是未執行的函數,如果我們想執行,就需要加上 ();
好了,這裡就是我所理解的 apply call bind的用法了。
其實他們的用法很基礎,但是他們可以改變this範圍的這個特點倒是殺傷力驚人。後面的章節我會重點講解this,爭取將其吃透。敬請期待。
前端見微知著JavaScript基礎篇:你所不知道的apply, call 和 bind