成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

前端Tank技能---模塊化加載器的簡單實(shí)現(xiàn)

ShevaKuilin / 2676人閱讀

摘要:拋開一直寫的那個(gè)不講,我們說的是一個(gè)簡單的模塊加載器的簡單實(shí)現(xiàn)。非常好實(shí)現(xiàn),忽略不提。是第一個(gè)冒出來的,但是,一般提到他都會(huì)是棄用的,會(huì)有安全的漏洞更好的方案是構(gòu)造器。

什么是模塊化,為什么要模塊化

裝個(gè)b,貼一段English

A beginning programmer writes her programs like an ant builds her hill, one piece at a time, without thought for the bigger structure. Her programs will be like loose sand. They may stand for a while, but growing too big they fall apart.

Realizing this problem, the programmer will start to spend a lot of time thinking about structure. Her programs will be rigidly structured, like rock sculptures. They are solid, but when they must change, violence must be done to them.

The master programmer knows when to apply structure and when to leave things in their simple form. Her programs are like clay, solid yet malleable.

Master Yuan-Ma, The Book of Programming

以上基本上是為什么要模塊化的,至于什么是模塊化有好多好多種。

比如這樣:

function dujia1(){
    //..
}

function dujia2(){
    //...
}

這樣簡單的放在一起也是模塊化,只不過太挫,有些人不承認(rèn)而已。

再比如這樣

var page = {
    init: function(){
        //..
    },
    getData:function(){
        //..    
    },
    bindEvent:function(){
        //...
    },
    __secret:”我不想讓讓人知道"
}

這個(gè)就是我們比價(jià)常用的了。所有page相關(guān)的功能都作為屬性包在page這個(gè)模塊里面,基本上對全局沒有污染。但是也沒有保留,也就是對外部來說,所有的東西都是可以看到的。
比如訪問 page.__secret 你能獲取這個(gè)秘密,這樣的包裝方式是包不住的。

再比如這樣:

var page = (function(){
    
    var  __secret = ”我不想讓讓人知道”;

    var init = function(){
        //..
    };
    var getData = function(){
        //..    
    };
    var bindEvent = function(){
        //...
    };

    return {
        init : init
    }    
})();

這樣呢外吐的只有init了。是吧,其他都包住了。

再比如一下這個(gè)樣子:

var page = (function(mod){
    mod.xxx=yyy;
    return mod
})(module);

好,這樣就可以擴(kuò)展module了。

其實(shí)以上都不是本篇的重點(diǎn),本篇的重點(diǎn)是模塊加載工具的簡單實(shí)現(xiàn)。

模塊加載器

以上大家都看到了,要實(shí)現(xiàn)模塊化,我們要設(shè)計(jì),要知道怎么搞好,然后呢用這個(gè)方法去實(shí)現(xiàn),啪啪啪寫好多代碼去實(shí)現(xiàn)。

那么換個(gè)思路想想,我們?yōu)槭裁床辉诖虬^程中編譯過程中或者加載過程中由程序去做這個(gè)事情呢。對,fekit是這樣實(shí)現(xiàn),好多好多都是這樣實(shí)現(xiàn)的,實(shí)現(xiàn)這樣功能的東西就是模塊加載器。

先說說,我們已經(jīng)寫的次數(shù)和名字差不多的 require是怎么實(shí)現(xiàn)的。

拋開一直寫的那個(gè)require不講,我們說的是一個(gè)簡單的模塊加載器的簡單實(shí)現(xiàn)。

定義一下:這個(gè)加載器,可以通過require一個(gè)文件的方式,把里面的內(nèi)容添加到require的文件中,并能夠執(zhí)行他。也就是通過傳入模塊名來取得該模塊的調(diào)用。

實(shí)現(xiàn)一個(gè)readFile方法,返回對應(yīng)文件的內(nèi)容;

將返回的字符串作為代碼進(jìn)行執(zhí)行。

readFile非常好實(shí)現(xiàn),忽略不提。

然后就是把字符串轉(zhuǎn)成可以執(zhí)行的程序代碼。eval是第一個(gè)冒出來的,但是,一般提到他都會(huì)是棄用的,會(huì)有安全的漏洞

更好的方案是Function構(gòu)造器。

var plus = new Function("name", "return name + ‘ bigger"");
console.log(plus("Iphone6")); //Iphone6 bigger

兩個(gè)參數(shù),第一個(gè)是用逗號分隔的參數(shù)列表字符串,第二個(gè)是函數(shù)體字符串

有了這個(gè)我們就可以來實(shí)現(xiàn)require方法了

//module.js

function require(name){

    //調(diào)用一個(gè)模塊,首先檢查這個(gè)模塊是否已經(jīng)調(diào)用
    if(name in require.cache){
        return require.cache[name];
    }

        //此處生成一個(gè)code的函數(shù),參數(shù)為  exports 和 module, 函數(shù)體為readFile返回的js文件中的代碼字符串
    var code = new Function("exports, module", readFile(name));
        
        //定義外吐內(nèi)容
    var exports = {},
        module = {exports: exports};
        
        //執(zhí)行函數(shù)體,如果有定義外吐,既module.exports 或者  exports.***之類的,會(huì)改寫上面的外吐內(nèi)容
    code(exports, module);

    require.cache[name] = module.exports;

        //返回exports
    return module.exports;
}

//緩存對象,為了應(yīng)對重復(fù)調(diào)用
require.cache = Object.create(null);

//讀文件,返回結(jié)果
function readFile(fileName){ ... }

這就是一個(gè)簡單的CommonJS模塊風(fēng)格的加載方式,也是node和fekit現(xiàn)在使用的加載方式。

實(shí)現(xiàn)demo

親測,不加demo很有可能看不懂

有一個(gè)文件 aaa.js,內(nèi)容如下

function (){
    console.log("this is aaa");
}
exports.aaa = "aaa";

這是var aaa = require("aaa.js")會(huì)做以下事情

readFile("aaa.js") 以字符串形式返回aaa的所有函數(shù)體,也就是上面的哪些部分代碼
通過new Function構(gòu)造器,創(chuàng)造一個(gè)code函數(shù),函數(shù)體是aaa.js里面的內(nèi)容
執(zhí)行code函數(shù),log出結(jié)果,然后擴(kuò)展了module.exports
返回這個(gè)module.exports 改外面的變量 aaa

再思考

我們在吐js模塊的時(shí)候經(jīng)常使用的方案是這樣兩種
# module.exports = a object;
# exports.aaa = function();

如果我們直接寫 exports = a object 會(huì)怎么樣,為什么?

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79657.html

相關(guān)文章

  • 前端Tank技能---頁面load事件分析

    摘要:事件詳細(xì)研究邊界事件外鏈樣式在某些瀏覽器下面會(huì)影響腳本的加載。事件和事件是同時(shí)的。這就是要監(jiān)聽頁面的事件,當(dāng)事件為時(shí)就可以開始做的事情了。 頁面加載狀態(tài) $(document).ready() $(function(){}) 這兩個(gè)是我們在頁面初始化時(shí)經(jīng)常使用的監(jiān)聽方案,那么他的實(shí)際的執(zhí)行關(guān)系時(shí)什么樣的呢?在原生js中是什么樣的一種表現(xiàn)? 以下我會(huì)一而再再而三的寫DOMConten...

    silencezwm 評論0 收藏0
  • 前端Tank技能---頁面load事件分析

    摘要:事件詳細(xì)研究邊界事件外鏈樣式在某些瀏覽器下面會(huì)影響腳本的加載。事件和事件是同時(shí)的。這就是要監(jiān)聽頁面的事件,當(dāng)事件為時(shí)就可以開始做的事情了。 頁面加載狀態(tài) $(document).ready() $(function(){}) 這兩個(gè)是我們在頁面初始化時(shí)經(jīng)常使用的監(jiān)聽方案,那么他的實(shí)際的執(zhí)行關(guān)系時(shí)什么樣的呢?在原生js中是什么樣的一種表現(xiàn)? 以下我會(huì)一而再再而三的寫DOMConten...

    lpjustdoit 評論0 收藏0
  • 前端Tank技能---瀏覽器嗅探

    摘要:由于那個(gè)時(shí)候是霸主,這也導(dǎo)致微軟推出的時(shí)候必須把自己偽裝成瀏覽器,于是他們的也是以開頭的。各個(gè)版本典型的如下其中之后的就是當(dāng)前的版本號。的幾個(gè)版本的其中之后的是版本號提供了專門的瀏覽器標(biāo)志,就是屬性。目前,的是其中,版本號在之后的數(shù)字。 瀏覽器嗅探 瀏覽器嗅探不用說了,為了更好的性能,會(huì)需要各種各樣的兼容性處理,自然就會(huì)有針對不同瀏覽器的判斷.一般的代碼中,我們都是通過navigato...

    Blackjun 評論0 收藏0
  • 前端相關(guān)大雜燴

    摘要:希望幫助更多的前端愛好者學(xué)習(xí)。前端開發(fā)者指南作者科迪林黎,由前端大師傾情贊助。翻譯最佳實(shí)踐譯者張捷滬江前端開發(fā)工程師當(dāng)你問起有關(guān)與時(shí),老司機(jī)們首先就會(huì)告訴你其實(shí)是個(gè)沒有網(wǎng)絡(luò)請求功能的庫。 前端基礎(chǔ)面試題(JS部分) 前端基礎(chǔ)面試題(JS部分) 學(xué)習(xí) React.js 比你想象的要簡單 原文地址:Learning React.js is easier than you think 原文作...

    fuyi501 評論0 收藏0
  • 設(shè)計(jì)模式之工廠模式

    摘要:缺點(diǎn)需要慎重考慮是否增加工廠類進(jìn)行管理,因?yàn)闀?huì)增加代碼的復(fù)雜度使用場景工廠模式是創(chuàng)建型模式的一種,其實(shí)就等價(jià)于對象,但是否將對象改造成工廠模式,使我們需要衡量的。 前言 最近北京天氣越來越冷了,同在北京的小伙伴大家注意保暖。不扯廢話了,讓我們直接進(jìn)入到工廠模式的學(xué)習(xí). 什么是工廠模式 定義一個(gè)用于創(chuàng)建對象的接口,讓子類決定實(shí)例化哪一個(gè)類。工廠方法使一個(gè)類的實(shí)例化延遲到子類。 UML類圖...

    huangjinnan 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<