<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 功能強大 支持多語言、二開方便! 廣告
                ### 1. 加載規則 瀏覽器加載 ES6 模塊,也使用`<script>`標簽,但是要加入`type="module"`屬性。 ~~~ <script type="module" src="./foo.js"></script> ~~~ 上面代碼在網頁中插入一個模塊`foo.js`,由于`type`屬性設為`module`,所以瀏覽器知道這是一個 ES6 模塊。 瀏覽器對于帶有`type="module"`的`<script>`,都是異步加載,不會造成堵塞瀏覽器,即等到整個頁面渲染完,再執行模塊腳本,等同于打開了`<script>`標簽的`defer`屬性。 ~~~ <script type="module" src="./foo.js"></script> <!-- 等同于 --> <script type="module" src="./foo.js" defer></script> ~~~ 如果網頁有多個`<script type="module">`,它們會按照在頁面出現的順序依次執行。 `<script>`標簽的`async`屬性也可以打開,這時只要加載完成,渲染引擎就會中斷渲染立即執行。執行完成后,再恢復渲染。 ~~~ <script type="module" src="./foo.js" async></script> ~~~ 一旦使用了`async`屬性,`<script type="module">`就不會按照在頁面出現的順序執行,而是只要該模塊加載完成,就執行該模塊。 ES6 模塊也允許內嵌在網頁中,語法行為與加載外部腳本完全一致。 ~~~ <script type="module"> import utils from "./utils.js"; // other code </script> ~~~ 舉例來說,jQuery 就支持模塊加載。 ~~~ <script type="module"> import $ from "./jquery/src/jquery.js"; $('#message').text('Hi from jQuery!'); </script> ~~~ * 模塊之中,頂層的`this`關鍵字返回`undefined`,而不是指向`window`。也就是說,在模塊頂層使用`this`關鍵字,是無意義的。 ### 2. ES6模塊與CommonJS中模塊的差異 它們有兩個重大差異。 * CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。 * CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。 第二個差異是因為 CommonJS 加載的是一個對象(即`module.exports`屬性),該對象只有在腳本運行完才會生成。而 ES6 模塊不是對象,它的對外接口只是一種靜態定義,在代碼靜態解析階段就會生成。 下面重點解釋第一個差異。 CommonJS 模塊輸出的是值的拷貝,也就是說,一旦輸出一個值,模塊內部的變化就影響不到這個值。請看下面這個模塊文件`lib.js`的例子。 ~~~javascript // lib.js var counter = 3; function incCounter() { counter++; } module.exports = { counter: counter, incCounter: incCounter, }; ~~~ 上面代碼輸出內部變量`counter`和改寫這個變量的內部方法`incCounter`。然后,在`main.js`里面加載這個模塊。 ~~~javascript // main.js var mod = require('./lib'); console.log(mod.counter); // 3 mod.incCounter(); console.log(mod.counter); // 3 ~~~ 上面代碼說明,`lib.js`模塊加載以后,它的內部變化就影響不到輸出的`mod.counter`了。這是因為`mod.counter`是一個原始類型的值,會被緩存。除非寫成一個函數,才能得到內部變動后的值。 ~~~javascript // lib.js var counter = 3; function incCounter() { counter++; } module.exports = { get counter() { return counter }, incCounter: incCounter, }; ~~~ 上面代碼中,輸出的`counter`屬性實際上是一個取值器函數。現在再執行`main.js`,就可以正確讀取內部變量`counter`的變動了。 ~~~bash $ node main.js 3 4 ~~~ ES6 模塊的運行機制與 CommonJS 不一樣。JS 引擎對腳本靜態分析的時候,遇到模塊加載命令`import`,就會生成一個只讀引用。等到腳本真正執行時,再根據這個只讀引用,到被加載的那個模塊里面去取值。換句話說,ES6 的`import`有點像 Unix 系統的“符號連接”,原始值變了,`import`加載的值也會跟著變。因此,ES6 模塊是動態引用,并且不會緩存值,模塊里面的變量綁定其所在的模塊。 還是舉上面的例子。 ~~~javascript // lib.js export let counter = 3; export function incCounter() { counter++; } // main.js import { counter, incCounter } from './lib'; console.log(counter); // 3 incCounter(); console.log(counter); // 4 ~~~ 上面代碼說明,ES6 模塊輸入的變量`counter`是活的,完全反應其所在模塊`lib.js`內部的變化。 ### 3. Node加載 Node 對 ES6 模塊的處理比較麻煩,因為它有自己的 CommonJS 模塊格式,與 ES6 模塊格式是不兼容的。目前的解決方案是,將兩者分開,ES6 模塊和 CommonJS 采用各自的加載方案。 Node 要求 ES6 模塊采用`.mjs`后綴文件名。也就是說,只要腳本文件里面使用`import`或者`export`命令,那么就必須采用`.mjs`后綴名。`require`命令不能加載`.mjs`文件,會報錯,只有`import`命令才可以加載`.mjs`文件。反過來,`.mjs`文件里面也不能使用`require`命令,必須使用`import`。 目前,這項功能還在試驗階段。安裝 Node v8.5.0 或以上版本,要用`--experimental-modules`參數才能打開該功能。 ~~~bash $ node --experimental-modules my-app.mjs ~~~ 為了與瀏覽器的`import`加載規則相同,Node 的`.mjs`文件支持 URL 路徑。 ~~~javascript import './foo?query=1'; // 加載 ./foo 傳入參數 ?query=1 ~~~ 上面代碼中,腳本路徑帶有參數`?query=1`,Node 會按 URL 規則解讀。同一個腳本只要參數不同,就會被加載多次,并且保存成不同的緩存。由于這個原因,只要文件名中含有`:`、`%`、`#`、`?`等特殊字符,最好對這些字符進行轉義。 目前,Node 的`import`命令只支持加載本地模塊(`file:`協議),不支持加載遠程模塊。 如果模塊名不含路徑,那么`import`命令會去`node_modules`目錄尋找這個模塊。 ~~~javascript import 'baz'; import 'abc/123'; ~~~ 如果模塊名包含路徑,那么`import`命令會按照路徑去尋找這個名字的腳本文件。 ~~~javascript import 'file:///etc/config/app.json'; import './foo'; import './foo?search'; import '../bar'; import '/baz'; ~~~ 如果腳本文件省略了后綴名,比如`import './foo'`,Node 會依次嘗試四個后綴名:`./foo.mjs`、`./foo.js`、`./foo.json`、`./foo.node`。如果這些腳本文件都不存在,Node 就會去加載`./foo/package.json`的`main`字段指定的腳本。如果`./foo/package.json`不存在或者沒有`main`字段,那么就會依次加載`./foo/index.mjs`、`./foo/index.js`、`./foo/index.json`、`./foo/index.node`。如果以上四個文件還是都不存在,就會拋出錯誤。 最后,Node 的`import`命令是異步加載,這一點與瀏覽器的處理方法相同。
                  <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>

                              哎呀哎呀视频在线观看