什麼是JavaScript對象動態加載
JavaScript動態加載(JavaScript Object Dynamic Loading) - 之所以叫做動態,是應為其有別與通常的靜態加載形式。
典型的JavaScript靜態加載方式,是通過<script>標簽將我們可能需要的所有JS文件依次嵌入到一個HTML頁面中,當浏覽器執行到<script> 標簽,就會到我們指定的地方去加載JavaScript並運行,這時,文件中定義的無論方法、類、對象等,已經存在與浏覽器,等待被使用。除非HTML頁面被Unload,否則這些東西就一直存在。
而典型的動態加載方式,是不需要任何提前的准備,只有當需要一個JavaScript對象來為我們服務時,我們就臨時去加載它所屬的JS文件,然後使用它,使用完畢,銷毀即可。正所謂“呼之即來,揮之即去”。
就因為這“呼之即來,揮之即去”的能力,使得JavaScript真正的活了起來。
JS動態加載解決了什麼問題
JS動態加載應該有什麼能力
傳統JS動態加載的實現
關於JS動態加載的實現,我見過很多種方法。早期的時候,人們想過很多辦法。這些辦法有自己發揮的空間,可以解決一些問題。但是都或多或少的存在弊端,以及實現上的繁瑣,最大的問題就是,它們基本都不是面向對象的。下面就列舉主要的2類:
可以看出以上兩種常見方式,都無法滿足我們的要求。
更優秀的解決方案
得益於神奇如阿拉丁神燈般的 eval() ,我們就可以實現以上所有的願望 :) 。
繞了那麼大圈子,想了那麼多辦法。其實最簡單的方法就在眼皮底下.
第一部分-調用方 main.js文件:
//動態讀取JS對象的方法
//@FileName:要讀取的JS對象URL,可以是本地路徑。
//@TheParameters:需要傳遞給被加載對象的參數,可以是任何對象。
function loadJSObj(FileName,TheParameters){
Ext.Ajax.request({ //異步調用方法
url: FileName, //調用URL
scope: this,
success: function(response){ //成功後的回調方法response為返回內容
var remoteObj = eval(response.responseText);
var mod = null;
mod = new remoteObj(TheParameters);return mod;
},
failure:function(){ //失敗後的回調方法
alert(name+' - 讀取失敗,請檢查網絡或文件。');return null;
}
});
}
這段代碼使用Extjs類庫封裝的異步讀取方法Ext.Ajax.request()。只是為了方便。如果你使用未封裝的XMLHttpRequest對象也沒什麼問題。
先大概說下loadJSObj方法干的事情是:
此處關鍵的代碼在於
var remoteObj = eval(response.responseText);
var mod = null;
mod = new remoteObj(TheParameters);return mod;
可以看到,我們直接將被讀取的JS文件傳進eval 函數執行。並返回一個叫做 remoteObj的東西,這個東西其實就是被讀取的JS的句柄(一個類,定義在被讀取JS中的類,後面會詳細說到),通過將remoteObj實例化,即mod = new remoteObj(參數) 就可以通過 mod 對象對被讀取的JS隨心所欲了操作了。
如此一來,遠程的JS就被我們按照參數中指定的要求實例化成本地對象了,可以使用了。但是…這只是一相情願。因為被讀取的JS得符合我們的要求,才能“兩廂情願”,最終得到結果…
第二部分 - 被調用方 login.js文件:
要想符合要求,被讀取的JS文件也必須按照一定的規則來寫。
//用戶登錄類
Ext.extend(eueuy.module,{
init:function(){
//==Variables==//
var userName = this.parameters.un; //獲取傳遞進來的參數un
var passWord = this.parameters.pwd; //獲取傳遞進來的參數pwd
//==Methods==//
//登錄方法
function loginOn(){
if (userName=='eueuy' || passWord=='123'){
return true;
}else{
return false;
}
}
//登出方法
function loginOff(){
alert('歡迎再來');}
}
});
我們先看看這個登錄類干了什麼:
沒有任何特別的東西,就是Ext.extend方法用的有點怪,區別於平常的 XXX = Ext.extend();
沒有賦值符號和類名。這恰恰是一個關鍵點:
類的名字必須留空
為什麼這樣寫?因為這樣一來,這個沒有類名的類, 就可以在eval()函數執行他的時候,再給他定義類名,這樣就將類名的定義留在了調用的時候