欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2017年07月31日 15:24:14   作者:方方和圓圓  
本篇文章主要介紹了ES6新特性:使用export和import實現(xiàn)模塊化詳解,具有一定的參考價值,有興趣的可以了解一下

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

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

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

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

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

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

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

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

4:一個模塊可以導(dǎo)入別的模塊

運行下面代碼

//lib.js
//導(dǎo)出常量
export const sqrt = Math.sqrt;
//導(dǎo)出函數(shù)
export function square(x) {
  return x * x;
}
//導(dǎo)出函數(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的基本語法:

第一種導(dǎo)出的方式:

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

運行下面代碼

//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();

第二種導(dǎo)出的方式:

在export接口的時候, 我們可以使用 XX as YY, 把導(dǎo)出的接口名字改了, 比如: 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);

第三種導(dǎo)出的方式:

這種方式是直接在export的地方定義導(dǎo)出的函數(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);

第四種導(dǎo)出的方式:

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

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

運行下面代碼

//lib.js
export default "string";

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

第五種導(dǎo)出方式:

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

運行下面代碼

//lib.js
let fn = () => "string";
export {fn as default};

//main.js
import defaultFn from "./lib";
console.log(defaultFn());

第六種導(dǎo)出方式:

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

運行下面代碼

//lib.js
export * from "./other";
//如果只想導(dǎo)出部分接口, 只要把接口名字列出來
//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提供相當(dāng)多導(dǎo)入以及導(dǎo)出的語法;

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

運行下面代碼

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

ES6導(dǎo)入的模塊都是屬于引用:

每一個導(dǎo)入的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ù)字或者字符串類型或者布爾值的原始值要被復(fù)制, 而不是賦址;

循環(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="http://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, 這種輸出結(jié)果和NodeJS輸出的情況是一樣的;

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

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

我使用ES6的模塊試一試, 只要每一個模塊被引用, 無論模塊是否執(zhí)行完畢, 該模塊的export已經(jīng)被導(dǎo)出了, 如果導(dǎo)出的是函數(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")}

如果導(dǎo)出的是字符串:

運行下面代碼

//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";

如果導(dǎo)出的是對象:

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

如果是數(shù)組:

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

如果是布爾值:

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

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

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

瀏覽器兼容:

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

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • D3.js實現(xiàn)餅狀圖的方法詳解

    D3.js實現(xiàn)餅狀圖的方法詳解

    相信大家都知道圖表是數(shù)據(jù)圖形化的表示,通過形象的圖表來展示數(shù)據(jù),比如條形圖,折線圖,餅圖等??梢暬瘓D表可以幫助開發(fā)者更容易理解復(fù)雜的數(shù)據(jù),提高生產(chǎn)的效率和Web應(yīng)用和項目的可靠性。現(xiàn)在就讓我們大家一起來學(xué)習(xí)用D3.js來實現(xiàn)餅圖的方法,有需要的可以參考借鑒。
    2016-09-09
  • JavaScript 瀏覽器對象模型BOM原理與常見用法實例分析

    JavaScript 瀏覽器對象模型BOM原理與常見用法實例分析

    這篇文章主要介紹了JavaScript 瀏覽器對象模型BOM原理與常見用法,結(jié)合實例形式詳細分析了JavaScript瀏覽器對象模型BOM基本概念、原理、使用方法及操作注意事項,需要的朋友可以參考下
    2019-12-12
  • JavaScript實現(xiàn)圖片放大鏡效果

    JavaScript實現(xiàn)圖片放大鏡效果

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)圖片放大鏡效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • 詳解JS WebSocket斷開原因和心跳機制

    詳解JS WebSocket斷開原因和心跳機制

    這篇文章主要介紹了JS WebSocket斷開原因和心跳機制,對websocket感興趣的同學(xué),可以參考下
    2021-05-05
  • D3.js實現(xiàn)餅圖,環(huán)圖,玫瑰圖的繪制

    D3.js實現(xiàn)餅圖,環(huán)圖,玫瑰圖的繪制

    這篇文章主要為大家介紹了如何利用D3.js中的d3.pie和d3.arc實現(xiàn)餅圖、環(huán)圖和玫瑰圖的繪制,文中的實現(xiàn)方法講解詳細,感興趣的可以嘗試一下
    2022-11-11
  • JavaScript使用鏈?zhǔn)椒椒ǚ庋bjQuery中CSS()方法示例

    JavaScript使用鏈?zhǔn)椒椒ǚ庋bjQuery中CSS()方法示例

    這篇文章主要介紹了JavaScript使用鏈?zhǔn)椒椒ǚ庋bjQuery中CSS()方法,結(jié)合具體實例形式分析了JS采用鏈?zhǔn)讲僮鞣椒ǚ庾Query中連綴操作實現(xiàn)css()方法的相關(guān)技巧,需要的朋友可以參考下
    2017-04-04
  • JSONP原理及簡單實現(xiàn)

    JSONP原理及簡單實現(xiàn)

    這篇文章主要介紹了JSONP原理及簡單實現(xiàn)的相關(guān)資料,非常不錯具有參考借鑒價值,需要的朋友可以參考下
    2016-06-06
  • js獲取表格的行數(shù)和列數(shù)的方法

    js獲取表格的行數(shù)和列數(shù)的方法

    這篇文章主要介紹了js獲取表格的行數(shù)和列數(shù)的方法,需要的朋友可以參考下
    2015-10-10
  • js實現(xiàn)鼠標(biāo)懸停圖片上時滾動文字說明的方法

    js實現(xiàn)鼠標(biāo)懸停圖片上時滾動文字說明的方法

    這篇文章主要介紹了js實現(xiàn)鼠標(biāo)懸停圖片上時滾動文字說明的方法,涉及js操作鼠標(biāo)事件的使用技巧,需要的朋友可以參考下
    2015-02-02
  • javascript 解析url的search方法

    javascript 解析url的search方法

    在做UI的時候 ,有時會要解析url的search部分,裝了一個實用方法,共享給大家。
    2010-02-02

最新評論