<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 前端模塊化 主要介紹CommonJS模塊 和 ES6模塊的區別,不感興趣可以跳過本節內容。 ## 1、ES6模塊 ES6 模塊的設計思想是盡量的靜態化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變量。 **1.1 CommonJs模塊運行時加載(對象),ES6模塊編譯時輸出接口** 引用[阮一峰老師的例子][1]來進行說明: CommonJS的輸出緩存機制,使得模塊被加載時,會被緩存起來,將整個模塊當作一個對象輸出。 ```js // CommonJS模塊 let { stat, exists, readFile } = require('fs'); // 等同于 let _fs = require('fs'); let stat = _fs.stat; let exists = _fs.exists; let readfile = _fs.readfile; ``` 上面代碼的實質是整體加載fs模塊(即加載fs的所有方法),生成一個對象(_fs),然后再從這個對象上面讀取 3 個方法。這種加載稱為“運行時加載”,因為只有運行時才能得到這個對象,導致完全沒辦法在編譯時做“靜態優化”。 并且,由于緩存機制,重復加載同一模塊,都只會在第一次加載時運行一次,以后再加載,就返回第一次運行的結果,除非手動清除系統緩存。 ES6 模塊不是對象,而是通過export命令顯式指定輸出的代碼,再通過import命令輸入。 ```js // ES6模塊 import { stat, exists, readFile } from 'fs'; ``` 上面代碼的實質是從fs模塊加載3個方法,其他方法不加載。這種加載稱為“編譯時加載”或者靜態加載,即 ES6 可以在編譯時就完成模塊加載,效率要比CommonJS模塊的加載方式高。當然,這也導致了沒法引用 ES6 模塊本身,因為它不是對象。 **1.2 CommonJs 模塊輸出的是一個值的復制,ES6模塊編譯時輸出接口(動態只讀引用)** CommonJs 模塊: 對于基本數據類型,屬于復制。即會被模塊緩存。同時,在另一個模塊可以對該模塊輸出的變量重新賦值,而不會影響其他模塊。 對于復雜數據類型,屬于淺拷貝。由于兩個模塊引用的對象指向同一個內存空間,因此對該模塊的值做修改時會影響另一個模塊。 ES6 模塊: ES6 模塊的運行機制與 CommonJS不一樣。JS引擎對腳本靜態分析的時候,遇到模塊加載命令import,就會生成一個只讀引用。等到腳本真正執行時,再根據這個只讀引用,到被加載的那個模塊里面去取值。 **1.3 對于循環引用的處理** CommonJS 模塊: 其重要特性是加載時執行,即腳本代碼在require的時候,就會全部執行。一旦出現某個模塊被"循環加載",就只輸出已經執行的部分,還未執行的部分不會輸出。 例如: ```js // a.js console.log('a start'); var b = require('./b.js'); console.log('a doing'); console.log(b); exports.a = 'a模塊的變量'; // b.js console.log('b start'); var a = require('./b'); console.log('b doing') console.log(a); exports.b = 'b模塊的變量'; // 要理解CommonJS模塊是同步執行 // 當執行 node a.js時,輸出為: // a start // b start // b doing // {} // a doing // {b: 'b模塊的變量'} ``` ES6 模塊: ES6 模塊是動態引用,如果使用import從一個模塊加載變量,那些變量不會被緩存,而是成為一個指向被加載模塊的引用,需要開發者自己保證,真正取值的時候能夠取到值。 上面例子的ES6改寫: ```js $ node –experimental-modules a.mjs // a.js console.log('a start'); import {b} from ./b.mjs'; console.log('a doing'); console.log(b); exports.a = 'a模塊的變量'; // b.js console.log('b start'); import {a} from ./a.mjs'; console.log('b doing') console.log(a); exports.b = 'b模塊的變量'; // 輸出 // b start // b ding // ReferenceError: a is not defined ``` 分析:執行a.mjs以后,引擎發現它加載了b.mjs,因此會優先執行b.mjs,然后再執行a.mjs。接著,執行b.mjs的時候,已知它從a.mjs輸入了foo接口,這時不會去執行a.mjs,而是認為這個接口已經存在了,繼續往下執行。執行到第三行console.log(foo)的時候,才發現這個接口根本沒定義,因此報錯。 解決方法: ```js // a.js // exports.a = 'a模塊的變量'; 改為 export function a () {console.log('a模塊的函數')} // b.js // exports.b = 'b模塊的變量'; export function b () {console.log('b模塊的函數')} // 輸出 // b start // b ding // [Function: a] // a start // b doing // [Funcion: b] ``` 分析:function a(){...}具有提升作用。因此,在import之前,已經存在函數a。 下面簡單介紹前端的其它模塊化規范。 ## 2、CommonJS規范 1、核心思想: > 把一個文件當做一個模塊,通過require方法同步加載模塊。 2、應用場景 > Node.js的服務端編程加載的模塊主要存在于服務器磁盤,所以加載速度較快,對node這種單線程,影響較小。因此,CommonJS同步加載模塊方案主要應用于**node**服務端。 3、不適用于瀏覽器環境 > 瀏覽器加載方式與服務端完全不同。如果瀏覽器請求服務器資源時,會由于某個請求加載的時間過長導致瀏覽器阻塞,不會往下執行,所以就會出現網頁打開緩慢的現象。并且,瀏覽器端是以插入&lt;script&gt;標簽的形式來加載資源(ajax方式不行,有跨域問題),沒辦法讓代碼同步執行,使用commonJS同步寫法會直接報錯。 4、示例 ```js // 1.js module.export = function() { say: function() { alert("你好"); } } // main.js var a = require('./a.js'); a.say(); ``` 瀏覽器環境下必須采用異步模式。所以就有了ES6模塊、 AMD,CMD 解決方案。 ## 3、AMD規范 AMD(異步模塊定義)是RequireJS在推廣過程中對模塊化定義的規范化產出。 1、核心思想: > 異步加載所需的模塊,然后在回調函數中執行主邏輯。 **可以并行加載多個模塊,等所有模塊都加載并且解釋執行完成后**,才會執行接下來的代碼, 2、吐槽點 > “提前執行”:所有依賴模塊會被預先下載,并且提前執行(不管該模塊的調用時機)。“提前執行”的性能消耗是不容忽視。 3、懶加載 > AMD保留了commonjs中的require、exprots、module這三個功能。因此,為了解決“提前執行”的性能消耗,依賴的模塊不寫在dependencies數組中, 4、示例 ```js // a.js define(function(){ return { say: function(){ console.log('hello, a.js'); } } }); // b.js define(function(){ return { say: function(){ console.log('hello, a.js'); } } }); // main.js require(['a', 'b'], function(a, b){ a.say(); $('#b').click(function(){ b.say(); }); }) // AMD懶加載方式 // main.js require(['a'], function(a){ a.say(); $('#b').click(function(){ require(['b'], function(b){ b.say(); }); }); }) ``` 這種懶加載減輕了初始化操作。**但是,在需要執行b.say\(\)時,需要實時下載代碼然后在回調中才能執行,用戶的操作會有明顯的延遲卡頓。** ## 4、CMD規范 CMD\(同步模塊定義\)是SeaJS\(淘寶團隊\)在推廣過程中對模塊化定義的規范化產。 1、示例 ```js // a.js define(function(require, exports, module){ return { say: function(){ console.log('hello, a.js'); } } }); // b.js define(function(require, exports, module){ return { say: function(){ console.log('hello, b.js'); } } }); // main.js define(function(require, exports, module){ var a = require('a'); a.say(); $('#b').click(function(){ var a = require('b'); b.say(); }); }); }) ``` a.js和b.js都會預先下載,但是,**b.js不會預先執行(即用即返回)。** [1]: http://es6.ruanyifeng.com/#docs/module-loader
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看