站長資訊網
        最全最豐富的資訊網站

        es6模塊輸出的值是拷貝的嗎

        不是,ES6模塊輸出的是值的引用,CommonJS模塊輸出的才是一個值的拷貝。在ES6模塊中,JS引擎對腳本靜態分析的時候,遇到模塊加載命令import,就會生成一個只讀引用;等到腳本真正執行時,再根據這個只讀引用,到被加載的那個模塊里面去取值。ES6模塊是動態引用,ES6模塊不會緩存運行結果,而是動態地去被加載的模塊取值,并且變量總是綁定其所在的模塊。

        es6模塊輸出的值是拷貝的嗎

        前端(vue)入門到精通課程:進入學習
        Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調試工具:點擊使用

        本教程操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。

        瀏覽器加載

        默認情況下,瀏覽器是同步加載 JavaScript 腳本的,即渲染引擎遇到<script>標簽就會停下來,等到執行完腳本,再繼續向下渲染。

        如果是外部腳本,還必須加入腳本下載的時間。

        如果腳本體積很大,下載和執行的時間就會很長,因此造成瀏覽器堵塞,用戶會感覺到瀏覽器“卡死”了,沒有任何響應。這顯然是很不好的體驗,所以瀏覽器允許腳本異步加載,下面就是兩種異步加載的語法。

        <script src="path/to/myModule.js" defer></script> <script src="path/to/myModule.js" async></script>
        登錄后復制

        <script>標簽打開defer或async屬性,腳本就會異步加載。渲染引擎遇到這一行命令,就會開始下載外部腳本,但不會等它下載和執行,而是直接執行后面的命令

        • defer要等到整個頁面在內存中正常渲染結束(DOM 結構完全生成,以及其他腳本執行完成),才會執行;
        • async一旦下載完,渲染引擎就會中斷渲染,執行這個腳本以后,再繼續渲染。

        一句話,defer是“渲染完再執行”,async是“下載完就執行”。另外,如果有多個defer腳本,會按照它們在頁面出現的順序加載,而多個async腳本是不能保證加載順序的。

        瀏覽器加載 ES6 模塊,也使用<script>標簽,但是要加入type="module"屬性。瀏覽器對于帶有type="module"<script>,都是異步加載不會造成堵塞瀏覽器,即等到整個頁面渲染完,再執行模塊腳本,等同于打開了

        <script type="module" src="./foo.js"></script>
        登錄后復制

        如果網頁有多個<script type="module">,它們會按照在頁面出現的順序依次執行

        注意:<script>標簽的async屬性也可以打開,這時只要加載完成,渲染引擎就會中斷渲染立即執行。執行完成后,再恢復渲染。一旦使用了async屬性,<script type="module">就不會按照在頁面出現的順序執行,而是只要該模塊加載完成,就執行該模塊。

        對于外部的模塊腳本(上例是foo.js),有幾點需要注意:

        • 代碼是在模塊作用域之中運行,而不是在全局作用域運行。模塊內部的頂層變量,外部不可見。
        • 模塊腳本自動采用嚴格模式,不管有沒有聲明use strict。
        • 模塊之中,可以使用import命令加載其他模塊(.js后綴不可省略,需要提供絕對 URL 或相對 URL),也可以使用export命令輸出對外接口。
        • 模塊之中,頂層的this關鍵字返回undefined,而不是指向window。也就是說,在模塊頂層使用this關鍵字,是無意義的。
        • 同一個模塊如果加載多次,將只執行一次

        ES6 模塊也允許內嵌在網頁中,語法行為與加載外部腳本完全一致。

        <script type="module">   import utils from "./utils.js";   // other code </script>
        登錄后復制

        ES6 模塊與 CommonJS 模塊的差異

        CommonJS 是同步加載模塊,ES6是異步加載模塊

        CommonJS規范加載模塊是同步的,也就是說,只有加載完成,才能執行后面的操作。由于Node.js主要用于服務器編程,模塊文件一般都已經存在于本地硬盤,所以加載起來比較快,不用考慮非同步加載的方式,所以CommonJS規范比較適用。

        但是,如果是瀏覽器環境,要從服務器端加載模塊,這時就必須采用異步模式

        瀏覽器加載 ES6 模塊是異步加載不會造成堵塞瀏覽器,即等到整個頁面渲染完,再執行模塊腳本


        CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。

        CommonJS 模塊輸出的是值的拷貝,也就是說,一旦輸出一個值,模塊內部的變化就影響不到這個值

        ES6 模塊的運行機制與 CommonJS 不一樣。JS 引擎對腳本靜態分析的時候,遇到模塊加載命令import,就會生成一個只讀引用等到腳本真正執行時,再根據這個只讀引用,到被加載的那個模塊里面去取值

        換句話說,ES6 的import有點像 Unix 系統的“符號連接”,原始值變了,import加載的值也會跟著變。因此,ES6 模塊是動態引用,ES6 模塊不會緩存運行結果,而是動態地去被加載的模塊取值,并且變量總是綁定其所在的模塊。

        由于 ES6 輸入的模塊變量,只是一個“符號連接”,所以這個變量是只讀的,對它進行重新賦值會報錯。上面代碼中,main.js從lib.js輸入變量obj,可以對obj添加屬性,但是重新賦值就會報錯。因為變量obj指向的地址是只讀的,不能重新賦值,這就好比main.js創造了一個名為obj的const變量。

        // lib.js export let obj = {}; // main.js import { obj } from './lib'; obj.prop = 123; // OK obj = {}; // TypeError
        登錄后復制

        此外,export通過接口,輸出的是同一個值。不同的腳本加載這個接口,得到的都是同樣的實例


        CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。

        因為 CommonJS 加載的是一個對象(即module.exports屬性),該對象只有在腳本運行完才會生成

        而 ES6 模塊不是對象,它的對外接口只是一種靜態定義,在代碼靜態解析階段就會生成

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 亚洲国产精品久久久久久| 亚洲精品视频在线| 久久亚洲欧美日本精品| 亚洲午夜成人精品电影在线观看| 精品久久久久久久久午夜福利| 亚洲成人国产精品| 国产精品乱视频| 精品欧洲av无码一区二区三区| 久久99精品国产| 成人精品视频一区二区三区| 亚洲国产91精品无码专区| 国产激情精品一区二区三区| 99国产精品国产精品九九| 亚洲精品成人无限看| 欧美激情精品久久久久久久九九九 | 在线亚洲精品自拍| 久久久久国产精品麻豆AR影院 | 亚洲精品成人网站在线观看| 国内精品久久久久久不卡影院| 一本色道久久88精品综合| 久久国产精品国语对白| 国产精品午夜一级毛片密呀| 91精品国产麻豆国产自产在线 | 久久久久成人精品无码| 国产精品自在拍一区二区不卡| 无码人妻精品中文字幕免费| 蜜桃麻豆www久久国产精品| 久久99国产精品成人欧美| 精品多毛少妇人妻AV免费久久| 999国内精品永久免费视频| 老司机午夜精品视频资源| 无码精品黑人一区二区三区| 亚洲午夜国产精品无码老牛影视| 91自慰精品亚洲| 国产精品免费久久| 国产在线精品一区二区三区不卡 | 91精品国产综合久久四虎久久无码一级| 日韩精品一区二区三区视频| 精品国产呦系列在线观看免费| 国产在线精品一区二区中文| 欧美精品亚洲精品日韩传电影|