js動態載入指令碼之實用小技巧

來源:互聯網
上載者:User

  最近我們公司的iClient產品需要改動,由於我們的包大概有1M了,使用者在使用的過程中如果網速不是很好的話,載入的就比較慢,使用者體驗就不好,上面要求使用者初始化的時候只有基礎包,比較小,當使用者用到哪一塊功能就載入哪塊的功能,這樣體驗上要好得多,但是我們的使用者已經有很多了,那麼我們就不能讓使用者改變以前的代碼,只能讓使用者把包替換一下,這裡研究了幾天研究了一種辦法和大家分享一下。對於做產品的朋友可能會有協助吧!

  對於產品包來說,無非就是N多的類。使用者一般使用的時候都是new一個對象,然後開始使用它!比如我們有一個Person類,這裡就會涉及到當瀏覽器運行到var person = new Person()這裡時,其實記憶體裡面還沒有這個類,我們並沒有在一開始就導進來,但是如果沒有的話瀏覽器肯定會報錯,那我們在new之前加一句代碼來導包,這樣不就是需要更改使用者的原始碼了嗎?肯定不可取。我們需要在瀏覽器new對象的時候把對應的類導進來,而又不改變任何原始碼,如何做到?

  我們可以在基礎包裡面對每一個類寫一個假的類,但是命名空間、類名必須都是一樣的,但類裡面除了建構函式什麼都沒有,這樣假類就很小,基本不會使基礎包的大小改變多少,這樣在瀏覽器運行到如var person = new Person()這一句的時候至少不會報告錯誤,但是產生的對象person是假的,停用,我們得想辦法讓它變成真的,怎麼才能讓new出的對象不是自己而是其他的對象呢?

  我嘗試了很多種辦法,比如在建構函式裡面改變過this.__proto__.constructor、this.__proto__、this等手段,希望最後new出來的對象不是自身,而和new Person(真的)一樣,但是你可以調試發現沒法做到一模一樣,最後無意間發現在建構函式裡面使用return就可以改變new出來的對象,如下面new Person()出一個對象。

        function Person()        {            return new Date();        }

  你會發現new出來的不是Person的對象,而是一個Date對象,而且和new Date()出來的對象一模一樣,這是js這門語言故意這樣設計吧!也不知道最開始的目的是啥!如果使用return;或者return null;最後new出來的對象還是本身。這樣第一個問題就解決了,可以new出一個非自身的對象。

  繼續討論,現在我們new出來的對象需要時真的那個類,而不是那個假的類,但是兩個類的命名空間和類名都是一樣的,這可怎麼辦,其實大家都知道所有的類無非就是window的屬性而已,其實都是指標,我把指向的部分改變後不久實現了嗎?

  我們先需要寫一個真的類,建立一個Person.js檔案,開啟後寫入如下代碼:

function Person(name,age){    this.name =  name;    this.age = age;    this.getName = function(){        return this.name;    }    this.getAge = function(){        return this.age;    }}

  這是一個真的類,有name和age兩個屬性以及getName()和getAge()兩個方法。在在同樣的檔案夾下建立一個html檔案,代碼如下:

<html><head>    <title></title>    <script type="text/javascript" src="loadJS.js"></script>    <script type="text/javascript">        function init()        {            var person = new Person("Bill",23);            var name = person.getName();            var age = person.getAge();            alert(name + "_" + age);        }        function Person(name,age)        {            loadJS("idPerson","Person.js");            return  new Person(name,age);        }    </script></head><body>    <button onclick="init()">測試</button></body></html>

  這裡有一個loadJS.js檔案,這是一個動態同步載入js檔案的一個包,我自己寫的,很簡單,裡面的內容詳見《js動態載入指令碼》裡面的第六種方法裡有原始碼,其實就一個方法loadJS(id,url)。上面代碼已經有一個假的Person存在了,裡面有兩句代碼,第一句是載入真的Person,第二句是返回一個Person對象,當我們調試的時候你會驚奇的發現,當真的Person載入進來後Person這個類就變成了真的類,而假的類在new以後就沒有了,因為沒有指標指向它了,它接下來就會被回收機制給回收掉,new玩後發現person就成為了真的那個Person的對象,當你再次new Person()的時候發現直接就是真的Person對象了,因為已經載入過一次了。

  我們仔細思考一下,如果Person這個類用到了我們其他沒載入的類,瀏覽器也會先尋找到假的那個類,再次去載入需要的類,這就形成了一個迴圈,需要什麼類的時候再載入什麼,不會多載入任何一個多餘的類。前提是你得每一個類對應一個js檔案。你也可以分成多少個模組,每個模組裡面有多個類,那麼每一次去載入就會載入一個模組,一個模組載入進來後會替換掉其中一部分假類。無論怎麼設計都很方便。

  好了,所有問題都解決了,我們需要把假的類封裝進我們的產品包,然後讓使用者把這個包替換掉,使用者不需要改變任何以前項目的原始碼,就可以做到動態載入需要的指令碼。這個辦法是不是很好用?好用就幫我頂一下!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.