<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        ES6新特性:使用export和import實現(xiàn)模塊化詳解

        來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 22:33:47
        文檔

        ES6新特性:使用export和import實現(xiàn)模塊化詳解

        ES6新特性:使用export和import實現(xiàn)模塊化詳解:在ES6前, 前端就使用RequireJS或者seaJS實現(xiàn)模塊化, requireJS是基于AMD規(guī)范的模塊化庫, 而像seaJS是基于CMD規(guī)范的模塊化庫, 兩者都是為了為了推廣前端模塊化的工具, 更多有關AMD和CMD的區(qū)別, 后面參考給了幾個鏈接; 現(xiàn)在ES6自帶了模塊化, 也是
        推薦度:
        導讀ES6新特性:使用export和import實現(xiàn)模塊化詳解:在ES6前, 前端就使用RequireJS或者seaJS實現(xiàn)模塊化, requireJS是基于AMD規(guī)范的模塊化庫, 而像seaJS是基于CMD規(guī)范的模塊化庫, 兩者都是為了為了推廣前端模塊化的工具, 更多有關AMD和CMD的區(qū)別, 后面參考給了幾個鏈接; 現(xiàn)在ES6自帶了模塊化, 也是

        在ES6前, 前端就使用RequireJS或者seaJS實現(xiàn)模塊化, requireJS是基于AMD規(guī)范的模塊化庫,  而像seaJS是基于CMD規(guī)范的模塊化庫,  兩者都是為了為了推廣前端模塊化的工具, 更多有關AMD和CMD的區(qū)別, 后面參考給了幾個鏈接;

        現(xiàn)在ES6自帶了模塊化, 也是JS第一次支持module, 在很久以后 ,我們可以直接作用import和export在瀏覽器中導入和導出各個模塊了, 一個js文件代表一個js模塊;

        現(xiàn)代瀏覽器對模塊(module)支持程度不同, 目前都是使用babelJS, 或者Traceur把ES6代碼轉化為兼容ES5版本的js代碼;

        ES6的模塊化的基本規(guī)則或特點:

        ES6的模塊化的基本規(guī)則或特點, 歡迎補充:

        1:每一個模塊只加載一次, 每一個JS只執(zhí)行一次, 如果下次再去加載同目錄下同文件,直接從內存中讀取。 一個模塊就是一個單例,或者說就是一個對象;

        2:每一個模塊內聲明的變量都是局部變量, 不會污染全局作用域;

        3:模塊內部的變量或者函數(shù)可以通過export導出;

        4:一個模塊可以導入別的模塊

        運行下面代碼

        //lib.js
        //導出常量
        export const sqrt = Math.sqrt;
        //導出函數(shù)
        export function square(x) {
         return x * x;
        }
        //導出函數(shù)
        export function diag(x, y) {
         return sqrt(square(x) + square(y));
        }
        
        //main.js
        import { square, diag } from './lib';
        console.log(square(11)); // 121
        console.log(diag(4, 3)); // 5
        
        
        
        

        下面列出幾種import和export的基本語法:

        第一種導出的方式:

        在lib.js文件中, 使用 export{接口} 導出接口, 大括號中的接口名字為上面定義的變量, import和export是對應的;

        運行下面代碼

        //lib.js 文件
        let bar = "stringBar";
        let foo = "stringFoo";
        let fn0 = function() {
         console.log("fn0");
        };
        let fn1 = function() {
         console.log("fn1");
        };
        export{ bar , foo, fn0, fn1}
        
        //main.js文件
        import {bar,foo, fn0, fn1} from "./lib";
        console.log(bar+"_"+foo);
        fn0();
        fn1();
        
        

        第二種導出的方式:

        在export接口的時候, 我們可以使用 XX as YY, 把導出的接口名字改了, 比如: closureFn as sayingFn, 把這些接口名字改成不看文檔就知道干什么的:

        運行下面代碼

        //lib.js文件
        let fn0 = function() {
         console.log("fn0");
        };
        let obj0 = {}
        export { fn0 as foo, obj0 as bar};
        
        //main.js文件
        import {foo, bar} from "./lib";
        foo();
        console.log(bar);
        

        第三種導出的方式:

        這種方式是直接在export的地方定義導出的函數(shù),或者變量:

        運行下面代碼

        //lib.js文件
        export let foo = ()=> {console.log("fnFoo") ;return "foo"},bar = "stringBar";
        
        //main.js文件
        import {foo, bar} from "./lib";
        console.log(foo());
        console.log(bar);
        
        

        第四種導出的方式:

        這種導出的方式不需要知道變量的名字, 相當于是匿名的, 直接把開發(fā)的接口給export;

        如果一個js模塊文件就只有一個功能, 那么就可以使用export default導出;

        運行下面代碼

        //lib.js
        export default "string";
        
        //main.js
        import defaultString from "./lib";
        console.log(defaultString);
        

        第五種導出方式:

        export也能默認導出函數(shù), 在import的時候, 名字隨便寫, 因為每一個模塊的默認接口就一個:

        運行下面代碼

        //lib.js
        let fn = () => "string";
        export {fn as default};
        
        //main.js
        import defaultFn from "./lib";
        console.log(defaultFn());
        

        第六種導出方式:

        使用通配符*  ,重新導出其他模塊的接口 (其實就是轉載文章, 然后不注明出處啦);

        運行下面代碼

        //lib.js
        export * from "./other";
        //如果只想導出部分接口, 只要把接口名字列出來
        //export {foo,fnFoo} from "./other";
        
        //other.js
        export let foo = "stringFoo", fnFoo = function() {console.log("fnFoo")};
        
        //main.js
        import {foo, fnFoo} from "./lib";
        console.log(foo);
        console.log(fnFoo());
        

        其他:ES6的import和export提供相當多導入以及導出的語法;

        在import的時候可以使用通配符*導入外部的模塊:

        運行下面代碼

        import * as obj from "./lib";
        console.log(obj);

        ES6導入的模塊都是屬于引用:

        每一個導入的js模塊都是活的, 每一次訪問該模塊的變量或者函數(shù)都是最新的, 這個是原生ES6模塊 與AMD和CMD的區(qū)別之一,以下代碼修改自http://exploringjs.com/es6/ch_modules.html#_imports-are-read-only-views-on-exports

        運行下面代碼

        //lib.js
        export let counter = 3;
        export function incCounter() {
         counter++;
        }
        export function setCounter(value) {
         counter = value;
        }
        
        
        //main.js
        import { counter, incCounter ,setCounter} from './lib';
        
        // The imported value `counter` is live
        console.log(counter); // 3
        incCounter();
        console.log(counter); // 4
        setCounter(0);
        console.log(counter); // 0
        
        

        在main.js中, counter一直指向lib.js中的局部變量counter, 按照JS的尿性, 像數(shù)字或者字符串類型或者布爾值的原始值要被復制, 而不是賦址;

        循環(huán)依賴的問題:

        NodeJS的循環(huán)依賴是這么處理的:打開;

        循環(huán)依賴是JS模塊化帶來的問題, 在瀏覽器端, 使用RequireJS測試模塊化, 比如有一個文件file0.js依賴于file1.js, 而file1.js又依賴于file0.js, 那么file0.js和file1.js到底誰先執(zhí)行?

        運行下面代碼

        //index.html
        <!DOCTYPE html>
        <html>
        <head>
         <title></title>
         <meta charset="utf-8"/>
        </head>
        <body>
        
        <script data-main="cyclic" src="https://www.gxlcms.com//cdn.bootcss.com/require.js/2.2.0/require.min.js"></script>
        <script>
        //cyclic.js
        require(["file0"], function(file0) {
         console.log(file0)
        })
        
        //file0.js
        define(["file1"], function(file1) {
         console.log(file1)
         return {
         file0 : "file0"
         }
        })
        
        //file1.js
        define(["file0"], function(file0) {
         console.log(file0);
         return {
         file1 : "file1"
         }
        })
        </script>
        </body>
        </html>
         
        
        

        在控制臺的依次輸出為:

        運行下面代碼

        undefined
        Object { file1: "file1" }
        Object { file0: "file0" }

        在執(zhí)行file1.js的時候file0.js還沒執(zhí)行完, 所以輸出了undefined, 這種輸出結果和NodeJS輸出的情況是一樣的;

        然后我又使用了司徒大神的mass-framework框架試了一下, 司徒大神的框架直接提示我: "模塊與之前的某些模塊存在循環(huán)依賴", 這樣還比較好點, requireJS對于循環(huán)依賴是直接執(zhí)行循環(huán)依賴的模塊, 會導致在開發(fā)的時候給自己挖坑....;

        接下來我又在babel-node下進行測試:下面是幾個測試,可以無視:

        我使用ES6的模塊試一試, 只要每一個模塊被引用, 無論模塊是否執(zhí)行完畢, 該模塊的export已經被導出了, 如果導出的是函數(shù):

        運行下面代碼 

        //cyclic.js
        import fn0 from "./file0";
        fn0();
        
        //file0.js
        import fn1 from "./file1";
        fn1();
        console.log("file0.js runs");
        export default function() {console.log("file0 export runs")}
        
        //file1.js
        import fn0 from "./file0";
        fn0();
        console.log("file1.js runs");
        export default function() {console.log("file1 export runs")}
        
        

        如果導出的是字符串:

        運行下面代碼

        //cyclic.js
        import str from "./file0";
        console.log(str);
        
        //file0.js
        import str1 from "./file1";
        console.log(str1)
        console.log("file0.js runs");
        export default "str0";
        
        //file1.js
        import str0 from "./file0";
        console.log(str0)
        console.log("file1.js runs");
        export default "str1";
        
        

        如果導出的是對象:

        那么第一行會先輸出一個初始值{},在最后等待file0.js和file1.js執(zhí)行完畢以后, 才輸出file0.js導出的對象;

        如果是數(shù)組:

        那么第一行會輸出一個被靜態(tài)分析過的初始值undefined,在最后等待file0.js和file1.js執(zhí)行完畢以后, 才輸出file0.js導出的對象;

        如果是布爾值:

        那么第一行會輸出一個被靜態(tài)分析過的初始值undefined,在最后等待file0.js和file1.js執(zhí)行完畢以后, 才輸出file0.js導出的布爾值;

        為什么會這樣呢? 我好像在這邊找到了答案:http://exploringjs.com/es6/ch_modules.html#_modules ,ES6的import和export被提前到js的最頂層, 在函數(shù)或者對象,或者基本值被導出去的時候提前被靜態(tài)分析過,參考:http://www.ecma-international.org/ecma-262/6.0/#sec-parsemodule , http://www.ecma-international.org/ecma-262/6.0/#sec-toplevelmoduleevaluationjob

        結論:用ES6的export導出數(shù)據(jù)接口的時候, 最好統(tǒng)一用函數(shù), 避免在循環(huán)依賴的時候, 因為JS會把不同類型的對象靜態(tài)解析成不同的初始值;

        瀏覽器兼容:

        1. chrome瀏覽器目前不支持import,和export;
        2. 火狐的支持也有限, 比chrome好;
        3. 我都用babel;

        聲明:本網(wǎng)頁內容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        ES6新特性:使用export和import實現(xiàn)模塊化詳解

        ES6新特性:使用export和import實現(xiàn)模塊化詳解:在ES6前, 前端就使用RequireJS或者seaJS實現(xiàn)模塊化, requireJS是基于AMD規(guī)范的模塊化庫, 而像seaJS是基于CMD規(guī)范的模塊化庫, 兩者都是為了為了推廣前端模塊化的工具, 更多有關AMD和CMD的區(qū)別, 后面參考給了幾個鏈接; 現(xiàn)在ES6自帶了模塊化, 也是
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 午夜爽爽爽男女免费观看影院| 国产成人无码免费网站| 免费国产污网站在线观看15| 亚洲乱亚洲乱少妇无码| 成年网站免费入口在线观看| 成人亚洲网站www在线观看| 国产亚洲视频在线观看网址| 国产精品无码免费视频二三区 | 亚洲综合综合在线| 久久99国产综合精品免费| 亚洲天天做日日做天天看| 99久9在线|免费| 亚洲免费在线观看视频| 美女视频黄是免费的网址| 亚洲精品国产国语| 日本免费高清一本视频| 男性gay黄免费网站| 国产成人毛片亚洲精品| 国内少妇偷人精品视频免费| 1区1区3区4区产品亚洲| 日韩免费a级毛片无码a∨| 成人亚洲国产精品久久| 亚洲日本中文字幕一区二区三区| 国产自国产自愉自愉免费24区 | 好吊色永久免费视频大全| 亚洲av无码一区二区乱子伦as | 免费人妻无码不卡中文字幕系| 亚洲成年人电影在线观看| 免费无码一区二区三区蜜桃大| 猫咪免费人成在线网站| 亚洲国产精品自在在线观看| 噼里啪啦免费观看高清动漫4| 亚洲精品国产suv一区88| 91麻豆国产自产在线观看亚洲| 一级毛片免费不卡在线| 亚洲人成图片网站| 亚洲精品久久久www| 久热中文字幕在线精品免费| 小说专区亚洲春色校园| 亚洲av无码一区二区三区乱子伦 | 性生交片免费无码看人|