javascript動態載入實現方法一

來源:互聯網
上載者:User

現在也有很多JS動態載入的架構,比如In.js。但是這種並不是我想要的編寫方式,我來說說我的想法。

先來一段java代碼 複製代碼 代碼如下:import Biz.User;
User u = new User();
u.show();

按流程就是導包、執行個體化、調用。

JS是做不了導包的,或者說代碼意義上的導包,一般只是在頁面上進行script標籤的引入。
那麼 先假設需要寫成這樣 複製代碼 代碼如下:Using("User");
var u = new User();
u.show();

那麼,在JS裡面可以實現嗎?

來一句一句的分析,當然,前提是頁面並不用script標籤載入user.js,不然就沒意義了。

第一句

Using("User");

為什麼用Using,當然只是我的一個命名想法而已,可以聯想一下C#,用的就是using,借來而已。

Using裡面寫入的當然是我需要的對象User,顧名思義,我當然寫成Using("User")了。先不說內裡是怎麼實現的,起碼思路是這樣。
因為不能類比關鍵字寫成 Using User;這種起碼我是做不到了。
第二句和第三句 複製代碼 代碼如下:var u = new User();
u.show();

很正常,就是很平常的執行個體化與函數調用,唯一不解的是User對象哪裡來的?那麼當然是第一句導包的時候匯入的。

流程就是這麼個流程,那麼到底能不能實現,關鍵就在第一句話。也就是說,到底能不能導包成功,而且該怎麼導包。

從script標籤吸引靈感,對,非同步載入所需要的js檔案。
也就是說 複製代碼 代碼如下:Using("User");

相當於寫了一句 複製代碼 代碼如下:<script type="text/javascript" src="user.js"></script>

現在這麼看下來,這麼做有意義嗎?就為把script標籤寫成JS動態引入的?或者,只為少寫幾個字元?

當然不能,這麼做毫無意義!那要怎麼做?
先從效率來講。
如果一個頁面需要載入N多js檔案的時候,如下 複製代碼 代碼如下:<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="view.js"></script>
<script type="text/javascript" src="register.js"></script>
<script type="text/javascript" src="validate.js"></script>
<script type="text/javascript" src="user.js"></script>
<script type="text/javascript" src="order.js"></script>
<script type="text/javascript" src="type.js"></script>

等等等等。

是不是很嚇人,那是相當嚇人,而且後期維護需要很高的成本,有多少頁面,可能就需要修改幾個頁面。那麼,當頁面只引入關鍵的幾個js檔案,其他檔案都採用動態載入的方式呢?
比如我們只需要載入jquery檔案,然後調用 複製代碼 代碼如下:$.getScript("user.js",function(){});

這樣,我們就做到分頁檔裡面只需要引入 複製代碼 代碼如下:<script type="text/javascript" src="jquery.min.js"></script>

即可。
那麼這種寫法的壞處在哪裡?看一段代碼 複製代碼 代碼如下:$.getScript("user.js",function(){
$.getScript("order.js",function(){
$.getScript("type.js",function(){
$.getScript("validate.js",function(){
// and so on..
});
});
});
});

PS:用In.js的watch函數是可以避免這種情況產生的。這不在本博文的考慮範圍了。

花眼嗎?還願意去對齊代碼嗎?即便有格式化工具,你還願意將閉合括弧與哪個$.getScript對應嗎?當然不願意。
那麼,仿java的導包形式應聲而出。 複製代碼 代碼如下:Using("User");
Using("Order");
Using("Type");
Using("Validate");
// and so on..

或者你願意,你可以 複製代碼 代碼如下:Using("User","Type","Order","Validate",...);

寫法問題 無所謂。當然我推薦使用第一種方法,清晰。

導包之後,所有的用法不需要任何嵌套,正常使用。 複製代碼 代碼如下:var u = new User();
var o = new Order();
// and so on..

但是會提出一個問題。假如非同步載入都在Using("XXX")的時候執行,那麼 複製代碼 代碼如下:Using("User");
Using("Order");
Using("Type");
Using("Validate");
// and so on..

這一段我就需要非同步載入4個檔案,雖然是非同步,但是未免有些麻煩?而且需要建立4個連結。你願意合并JS的話,也可以。而且,Using的時候我是不需要使用對象的,這個時候未免太浪費資源了?

至於這個問題,我的解決辦法就是學習hibernate,消極式載入,按需載入。
那麼怎麼做呢? 複製代碼 代碼如下:Using("User");

這個時候肯定是不載入,不載入做什嗎?當然是返回一個mock,也就是類比對象。給使用者先用著,只有當使用者真正需要使用這個對象的時候,再去載入所需的js。也就是說 複製代碼 代碼如下:Using("User"); // 這句話執行完畢之後會建立一個User對象,當時僅僅是個mock
var u = new User(); // 這個時候用需要的是真實的User對象執行個體,就在這個時候去動態載入JS檔案,並且返回已經執行個體化的User對象

大家都知道,非同步載入是與當前啟動並執行狀態不衝突的,也就是說 複製代碼 代碼如下:var u = new User();

這句話執行之後,u是一個沒有實際意義值的變數,而已。那麼,怎麼解決這個問題,我暫且想到的辦法,只能是採用同步策略了。只有當js載入完畢,再去執行之後的js語句,這個地方有點遺憾,而且同步可能帶來的瀏覽器假死,也是一個比較嚴重的問題,暫且不顧這些問題,希望以後能有更好的辦法解決。

那問題出來了,這麼做同步,有什麼優勢嗎?
我不知道有什麼優勢,起碼對比非同步載入,應該沒有劣勢。比如正常的非同步載入為 複製代碼 代碼如下:$.getScript("user.js",function(){
var u = new User();
});

單單執行這個語句,要執行到function,本質上也是等user.js載入完畢才會執行,那麼對比 複製代碼 代碼如下:var u = new User();

理論上時間應該相當,因為都是等user.js載入完畢之後才執行的。

起碼第二種看起來更像java式的代碼,不必理會其他非業務相關的代碼。

那麼,怎麼會知道需要的對象在什麼地方,怎麼載入進來?我能想到的就是類比一個設定檔,為什麼用設定檔,而不是像In.js用add函數或者其他架構的類似於register的函數,大概我只是想用設定檔,更像java,而且後期的修改起來也會更解耦一些吧。 複製代碼 代碼如下:Using.Config = {
"User" : "/js/user" // 可以隱去.js 因為肯定是載入JS檔案了
}

整個思路大概就是這個樣子,我在其基礎上進行了一些約束,比如加入了命名空間 複製代碼 代碼如下:var u = new Using.Modules.User();

這樣可以減少一些全域變數,而且有需要的話,可以插入一些所有對象可能都具有的共性,減少建立類時的重複編碼。

當然,也還是支援不使用命名空間的。

為瞭解決這個約束的效力,加入了Class.create函數來進行類建立約束。 複製代碼 代碼如下:Using.Class.create("User",function(){
}).property({
}).static({
}).namespace(Using.Modules);

這裡的大概意思就是

create(類名,建構函式)
property(類的屬性)
static(類的靜態屬性)
namespace(命名空間)

引申到此,為何不加入MVC形式?
後來我發現,要MVC,那麼幾個類之間的動態維護,或者建立之時就由Using這個類來自動維護,暫時還沒想到好的解決辦法,所以沒有加入其中,只能自己建立類,自己維護了.

通過上面的文字,最後得到一個Using.js
然後在頁面裡面就只需要引入一個 複製代碼 代碼如下:<script type="text/javascript" src="using.js"></script>

這樣接下來就可以寫 複製代碼 代碼如下:Using("jquery");
Using("User");

$("#ID").click(function(){
var user = new User();
user.name = "xx";
user.show();
});

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.