ES6 雖提供了許多新特性,但咱們實際工做中用到頻率較高並很少,根據二八法則,咱們應該用百分之八十的精力和時間,好好專研這百分之二十核心特性,將會收到事半功倍的奇效!寫文章不容易,請你們多多支持與關注!本文首發地址GitHub博客(含思惟導圖)
javascript
這部分着重介紹:babel 編譯ES6語法,如何用webpack實現模塊化。html
ES6 提供了許多新特性,但並非全部的瀏覽器都可以完美支持。下圖是各個瀏覽器對ES6兼容性一覽表(以export爲例)java
由上圖可知,有些瀏覽器對於ES6並非很友好,針對 ES6 的兼容性問題,不少團隊爲此開發出了多種語法解析轉換工具(好比babel,jsx,traceur 等),能夠把咱們寫的 ES6 語法轉換成 ES5,至關於在 ES6 和瀏覽器之間作了一個翻譯官。其中Babel是一個普遍使用的轉碼器,能夠將ES6代碼轉爲ES5代碼,從而在現有環境執行。node
·首先要先安裝node.js,運行npm init,而後會生成package.json文件 ·npm install --save-dev babel-core babel-preset-es2015 babel-preset-latest ·建立並配置.babelrc文件//存放在項目的根目錄下,與node_modules同級 ·npm install -g babel-cli ·babel-version
Babel的配置文件是.babelrc,存放在項目的根目錄下。該文件用來設置轉碼規則和插件,具體內容以下:webpack
//.babelrc文件 { "presets": ["es2015", "latest"], "plugins": [] }
·建立./src/index.js ·內容:[1,2,3].map(item=>item+1); ·運行babel./src/index.js
運行後獲得如下部分,說明已經成功配置了babelgit
"use strict"; [1, 2, 3].map(function (item) { return item + 1; });
現今的不少網頁其實能夠看作是功能豐富的應用,它們擁有着複雜的JavaScript代碼和一大堆依賴包,模快化工具就應運而生了,其中webpack 功能強大深受人們喜好。
Webpack的工做方式是:把你的項目當作一個總體,經過一個給定的主文件(如:index.js),Webpack將從這個文件開始找到你的項目的全部依賴文件,使用loaders處理它們,最後打包爲一個(或多個)瀏覽器可識別的JavaScript文件。
程序員
·npm install webpack babel-loader --save-dev ·建立並配置 webpack.config.js//webpack.config.js文件與package.json同級 ·配置 package.json中的scripts ·運行 npm start
//配置 webpack.config.js 針對.js結尾的文件除了node_modules都用babel解析 module.exports = { entry: './src/index.js', output: { path: __dirname, filename: './build/bundle.js' }, module: { rules: [{ test: /\.js?$/, exclude: /(node_modules)/, loader: 'babel-loader' }] } }
//配置 package.json中的scripts "scripts": { "start": "webpack", "test": "echo \"Error: no test specified\" && exit 1" }
ES5 只有全局做用域和函數做用域(例如,咱們必須將代碼包在函數內來限制做用域),這致使不少問題:es6
狀況1:內層變量覆蓋外層變量github
var tmp = new Date(); function f() { console.log(tmp); //undefined if (false) { var tmp = "hello world"; } }
狀況2:變量泄露,成爲全局變量web
var s = 'hello'; for (var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 5
ES6 提供 let 和 const 來代替 var 聲明變量,新的聲明方式支持用大括號表示的塊級做用域,這會帶來一些好處:
1.再也不須要當即執行的函數表達式(IIFE)
在 ES5 中,咱們須要構造一個當即執行的函數表達式去保證咱們不污染全局做用域。在 ES6中, 咱們可使用更簡單的大括號({}),而後使用 const 或者 let 代替 var 來達到一樣的效果。
2.循環體中的閉包再也不有問題
在 ES5 中,若是循環體內有產生一個閉包,訪問閉包外的變量,會產生問題。在 ES6,你可使用 「let」 來避免問題。
3.防止重複聲明變量
ES6 不容許在同一個做用域內用 let 或 const 重複聲明同名變量。這對於防止在不一樣的 js 庫中存在重複聲明的函數表達式十分有幫助。
若是一個對象的全部鍵名都是正整數或零,而且有length屬性,那麼這個對象就很像數組,稱爲僞數組。典型的僞數組有函數的arguments對象,以及大多數 DOM 元素集,還有字符串。
... <button>測試1</button> <br> <button>測試2</button> <br> <button>測試3</button> <br> <script type="text/javascript"> let btns = document.getElementsByTagName("button") console.log("btns",btns);//獲得一個僞數組 btns.forEach(item=>console.log(item)) Uncaught TypeError: btns.forEach is not a function </script>
針對僞數組,沒有數組通常方法,直接遍歷便會出錯,ES6新增Array.from()方法來提供一種明確清晰的方式以解決這方面的需求。
Array.from(btns).forEach(item=>console.log(item))將僞數組轉換爲數組
當調用 new Array( )構造器時,根據傳入參數的類型與數量的不一樣,實際上會致使一些不一樣的結果, 例如:
let items = new Array(2) ; console.log(items.length) ; // 2 console.log(items[0]) ; // undefined console.log(items[1]) ;
let items = new Array(1, 2) ; console.log(items.length) ; // 2 console.log(items[0]) ; // 1 console.log(items[1]) ; // 2
當使用單個數值參數來調用 Array 構造器時,數組的長度屬性會被設置爲該參數。 若是使用多個參數(不管是否爲數值類型)來調用,這些參數也會成爲目標數組的項。數組的這種行爲既混亂又有風險,由於有時可能不會留意所傳參數的類型。
ES6 引入了Array.of( )方法來解決這個問題。該方法的做用很是相似Array構造器,但在使用單個數值參數的時候並不會致使特殊結果。Array.of( )方法總會建立一個包含全部傳入參數的數組,而無論參數的數量與類型:
let items = Array.of(1, 2); console.log(items.length); // 2 console.log(items[0]); // 1 console.log(items[1]); // 2 items = Array.of(2); console.log(items.length); // 1 console.log(items[0]); // 2
Array.of基本上能夠用來替代Array()或newArray(),而且不存在因爲參數不一樣而致使的重載,並且他們的行爲很是統一。
數組實例的find方法,用於找出第一個符合條件的數組成員。它的參數是一個回調函數,全部數組成員依次執行該回調函數,直到找出第一個返回值爲true的成員,而後返回該成員。若是沒有符合條件的成員,則返回undefined。
[1, 4, -5, 10].find((n) => n < 0) // -5
數組實例的findIndex方法的用法與find方法很是相似,返回第一個符合條件的數組成員的位置,若是全部成員都不符合條件,則返回-1。
[1, 5, 10, 15].findIndex(function(value, index, arr) { return value > 9; }) // 2
Array.prototype.includes方法返回一個布爾值,表示某個數組是否包含給定的值。該方法的第二個參數表示搜索的起始位置,默認爲0。若是第二個參數爲負數,則表示倒數的位置,若是這時它大於數組長度(好比第二個參數爲-4,但數組長度爲3),則會重置爲從0開始。
[1, 2, 3].includes(2) // true [1, 2, 3].includes(3, -1); // true [1, 2, 3, 5, 1].includes(1, 2); // true
沒有該方法以前,咱們一般使用數組的indexOf方法,檢查是否包含某個值。indexOf方法有兩個缺點,一是不夠語義化,它的含義是找到參數值的第一個出現位置,因此要去比較是否不等於-1,表達起來不夠直觀。二是,它內部使用嚴格相等運算符(===)進行判斷,這會致使對NaN的誤判。
[NaN].indexOf(NaN) // -1 [NaN].includes(NaN) // true
ES6 提供entries(),keys()和values(),用於遍歷數組。它們都返回一個遍歷器對象,能夠用for...of循環進行遍歷,惟一的區別是keys()是對鍵名的遍歷、values()是對鍵值的遍歷,entries()是對鍵值對的遍歷。
for (let index of ['a', 'b'].keys()) { console.log(index); } // 0 // 1 for (let elem of ['a', 'b'].values()) { console.log(elem); } // 'a' // 'b' for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); } // 0 "a" // 1 "b"
ES6 容許使用「箭頭」(=>)定義函數。它主要有兩個做用:縮減代碼和改變this指向,接下來咱們詳細介紹:
const double1 = function(number){ return number * 2; //ES5寫法 } const double2 = (number) => { return number * 2; //ES6寫法 } const double4 = number => number * 2; //能夠進一步簡化
多個參數記得加括號
const double6 = (number,number2) => number + number2;
若是箭頭函數的代碼塊部分多於一條語句,就要使用大括號將它們括起來,而且使用return語句返回。
const double = (number,number2) => { sum = number + number2 return sum; }
因爲大括號被解釋爲代碼塊,因此若是箭頭函數直接返回一個對象,必須在對象外面加上括號,不然會報錯。
// 報錯 let getTempItem = id => { id: id, name: "Temp" }; // 不報 let getTempItem = id => ({ id: id, name: "Temp" });
此外還有個好處就是簡化回調函數
// 正常函數寫法 [1,2,3].map(function (x) { return x * x; }); // 箭頭函數寫法 [1,2,3].map(x => x * x);//[1, 4, 9]
長期以來,JavaScript 語言的this對象一直是一個使人頭痛的問題,在對象方法中使用this,必須很是當心。箭頭函數」綁定」this,很大程度上解決了這個困擾。咱們不妨先看一個例子:
const team = { members:["Henry","Elyse"], teamName:"es6", teamSummary:function(){ return this.members.map(function(member){ return `${member}隸屬於${this.teamName}小組`; // this不知道該指向誰了 }) } } console.log(team.teamSummary());//["Henry隸屬於undefined小組", "Elyse隸屬於undefined小組"]
teamSummary函數裏面又嵌了個函數,這致使內部的this的指向發生了錯亂。
那如何修改:
方法1、let self = this
const team = { members:["Henry","Elyse"], teamName:"es6", teamSummary:function(){ let self = this; return this.members.map(function(member){ return `${member}隸屬於${self.teamName}小組`; }) } } console.log(team.teamSummary());//["Henry隸屬於es6小組", "Elyse隸屬於es6小組"]
方法2、bind函數
const team = { members:["Henry","Elyse"], teamName:"es6", teamSummary:function(){ return this.members.map(function(member){ // this不知道該指向誰了 return `${member}隸屬於${this.teamName}小組`; }.bind(this)) } } console.log(team.teamSummary());//["Henry隸屬於es6小組", "Elyse隸屬於es6小組"]
方法3、 箭頭函數
const team = { members:["Henry","Elyse"], teamName:"es6", teamSummary:function(){ return this.members.map((member) => { // this指向的就是team對象 return `${member}隸屬於${this.teamName}小組`; }) } } console.log(team.teamSummary());//["Henry隸屬於es6小組", "Elyse隸屬於es6小組"]
(1)函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。
(2)不能夠看成構造函數,也就是說,不可使用new命令,不然會拋出一個錯誤。
(3)不可使用arguments對象,該對象在函數體內不存在。若是要用,能夠用 rest 參數代替。
(4)不可使用yield命令,所以箭頭函數不能用做 Generator 函數。
ES6 引入 rest 參數(形式爲...變量名),用於獲取函數的多餘參數,這樣就不須要使用arguments對象了。
rest 參數搭配的變量是一個數組,該變量將多餘的參數放入數組中。
咱們舉個例子:如何實現一個求和函數?
傳統寫法:
function addNumbers(a,b,c,d,e){ var numbers = [a,b,c,d,e]; return numbers.reduce((sum,number) => { return sum + number; },0) } console.log(addNumbers(1,2,3,4,5));//15
ES6寫法:
function addNumbers(...numbers){ return numbers.reduce((sum,number) => { return sum + number; },0) } console.log(addNumbers(1,2,3,4,5));//15
也能夠與解構賦值組合使用
var array = [1,2,3,4,5,6]; var [a,b,...c] = array; console.log(a);//1 console.log(b);//2 console.log(c);//[3, 4, 5, 6]
rest 參數還能夠與箭頭函數結合
const numbers = (...nums) => nums; numbers(1, 2, 3, 4, 5)// [1,2,3,4,5]
注意:①每一個函數最多隻能聲明一個rest參數,並且 rest參數必須是最後一個參數,不然報錯。
②rest參數不能用於對象字面量setter之中
let object = { set name(...value){ //報錯 //執行一些邏輯 } }
與剩餘參數關聯最密切的就是擴展運算符。剩餘參數容許你把多個獨立的參數合併到一個數組中;而擴展運算符則容許將一個數組分割,並將各個項做爲分離的參數傳給函數。
當用在字符串或數組前面時稱爲擴展運算符,我的以爲能夠理解爲rest參數的逆運算,用於將數組或字符串進行拆解。有些時候,函數不容許傳入數組,此時使用展開運算符就很方便,不信的話,我們看個例子:Math.max()方法,它接受任意數量的參數,並會返回其中的最大值。
let value1 = 25, let value2 = 50; console.log(Math.max(value1, value2)); // 50
但若想處理數組中的值,此時該如何找到最大值?Math.max()方法並不容許你傳入一個數組。其實你能夠像使用rest參數那樣在該數組前添加...,並直接將其傳遞給 Math.max()
let values = [25,50,75, 100] //等價於console.log(Math.max(25,50,75,100)); console.log(Math.max(...values)); //100
擴展運算符還能夠與其餘參數混用
let values = [-25,-50,-75,-100] console.log(Math.max(...values,0)); //0
擴展運算符拆解字符串與數組
var array = [1,2,3,4,5]; console.log(...array);//1 2 3 4 5 var str = "String"; console.log(...str);//S t r i n g
還能夠實現拼接
var defaultColors = ["red","greed"]; var favoriteColors = ["orange","yellow"]; var fallColors = ["fire red","fall orange"]; console.log(["blue","green",...fallColors,...defaultColors,...favoriteColors] //["blue", "green", "fire red", "fall orange", "red", "greed", "orange", "yellow"]
ES6 新增瞭解構,這是將一個數據結構分解爲更小的部分的過程。
在ES5及更早版本中,從對象或數組中獲取信息、並將特定數據存入本地變量,須要書寫許多而且類似的代碼。例如:
var expense = { type: "es6", amount:"45" }; var type = expense.type; var amount = expense.amount; console.log(type,amount);
此代碼提取了expense對象的type與amount值,並將其存在同名的本地變量上。雖然 這段代碼看起來簡單,但想象一下如有大量變量須要處理,你就必須逐個爲其賦值;而且如有一個嵌套的數據結構須要遍歷以尋找信息,你可能會爲了一點數據而挖掘整個結構。
這就是ES6爲什麼要給對象與數組添加解構。當把數據結構分解爲更小的部分時,從中提取你要的數據會變得容易許多。
上個例子中若是採用對象解構的方法,就很容易獲取expense對象的type與amount值。
const { type,amount } = expense; console.log(type,amount);
咱們再來看個例子:
let node = {type:"Identifier", name:"foo"}, type = "Literal",name = 5; ({type,name}= node);// 使用解構來分配不一樣的值 console.log(type); // "Identifier" console.log(name); // "foo"
注意:你必須用圓括號包裹解構賦值語句,這是由於暴露的花括號會被解析爲代碼塊語句,而塊語句不容許在賦值操做符(即等號)左側出現。圓括號標示了裏面的花括號並非塊語句、而應該被解釋爲表達式,從而容許完成賦值操做。
默認值:
能夠選擇性地定義一個默認值,以便在指定屬性不存在時使用該值。若要這麼作,須要在 屬性名後面添加一個等號並指定默認值,就像這樣:
let node = { type: "Identifier", name: "foo" }; let { type, name, value = true } = node; console.log(type); // "Identifier" console.log(name); // "foo" console.log(value); // true
嵌套對象解構:
使用相似於對象字面量的語法,能夠深刻到嵌套的對象結構中去提取你想要的數據。
let node = { type: "Identifier", name: "foo", loc: { start: { line: 1, column: 1 }, end: { line: 1, column: 4 } } }; let { loc: { start }} = node; console.log(start.line); // 1 console.log(start.column); // 1
本例中的解構模式使用了花括號,表示應當下行到node對象的loc屬性內部去尋找start屬性。
必須傳值的解構參數
function setCookie(name, value, { secure, path, domain, expires }) { // 設置cookie的代碼 } setCookie("type", "js");//報錯
在此函數內,name與value參數是必需的,而secure、path、domain與expires則不是。默認狀況下調用函數時未給參數解構傳值會拋出錯誤。像上例中若是setCookie不傳第三個參數,就會報錯。若解構參數是可選的,能夠給解構的參數提供默認值來處理這種錯誤。
function setCookie(name, value, { secure, path, domain, expires } = {}) {} setCookie("type", "js");//不會報錯
const names = ["Henry","Bucky","Emily"]; const [name1,name2,name3] = names; console.log(name1,name2,name3);//Henry Bucky Emily const [name,...rest] = names;//結合展開運算符 console.log(rest);//["Bucky", "Emily"]
用{}解構返回數組個數
const {length} = names; console.log(length);//3
數組解構也能夠用於賦值上下文,但不須要用小括號包裹表達式。這點跟對象解構的約定不一樣。
let colors = ["red", "green", "blue"], firstColor = "black", secondColor = "purple"; [firstColor, secondColor] = colors; console.log(firstColor); // "red" console.log(secondColor); // "green"
默認值:數組解構賦值一樣容許在數組任意位置指定默認值。當指定位置的項不存在、或其值爲undefined,那麼該默認值就會被使用。
let colors = ["red"]; let [firstColor, secondColor = "green"] = colors; console.log(firstColor); // "red" console.log(secondColor);// "green"
與rest參數搭配
在ES5中經常使用concat()方法來克隆數組,例如:
//在ES5中克隆數組 var colors = ["red", "green", "blue"]; var clonedColors = colors.concat(); console.log(clonedColors); //"[red,green,blue]"
在ES6中,你可使用剩餘項的語法來達到一樣效果
//在ES6中克隆數組 let colors = ["red", "green", "blue"]; let [...clonedColors] = colors; console.log(clonedColors); //[red,green,blue]
接下咱們看個例子:如何將數組轉化爲對象
const points = [ [4,5], [10,1], [0,40] ]; //指望獲得的數據格式以下,如何實現? // [ // {x:4,y:5}, // {x:10,y:1}, // {x:0,y:40} // ] let newPoints = points.map(pair => { const [x,y] = pair; return {x,y} }) //還能夠經過如下辦法,更爲簡便 let newPoints = points.map(([x,y]) => { return {x,y} }) console.log(newPoints);
混合解構
const people = [ {name:"Henry",age:20}, {name:"Bucky",age:25}, {name:"Emily",age:30} ]; //es5 寫法 var age = people[0].age; console.log(age); //es6 解構 const [age] = people; console.log(age);//第一次解構數組 {name:"Henry",age:20} const [{age}] = people;//再一次解構對象 console.log(age);//20
當使用解構來配合var、let、const來聲明變量時,必須提供初始化程序(即等號右邊的值)。下面的代碼都會由於缺失初始化程序而拋出語法錯誤:
var { type, name }; // 語法錯誤! let { type, name }; // 語法錯誤! const { type, name }; // 語法錯誤!
模板字符串是加強版的字符串,用反引號(`)標識。**它能夠看成普通字符串使用,也能夠用來定義多行字符串,或者在字符串中嵌入變量。
模板字符串中嵌入變量和函數,須要將變量名寫在${}之中。**
let name = "Henry"; function makeUppercase(word){ return word.toUpperCase(); } let template = ` <h1>${makeUppercase('Hello')}, ${name}!</h1>//能夠存放函數和變量 <p>感謝你們收看咱們的視頻, ES6爲咱們提供了不少遍歷好用的方法和語法!</p> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> `; document.getElementById('template').innerHTML = template;
再舉個例子,工做中經常使用到ElementUI庫,在自定義一個彈出框時,使用模板字符串就很方便:
await this.$alert( `<p><strong>確認是否升級${ this.lectureName }</strong><br>(若已存在講義套件,升級後請從新生成)</p>`, { dangerouslyUseHTMLString: true } )
從概念上講,在 ES6 以前的 JS 中並無和其餘面嚮對象語言那樣的「類」的概念。長時間裏,人們把使用 new 關鍵字經過函數(也叫構造器)構造對象當作「類」來使用。因爲 JS 不支持原生的類,而只是經過原型來模擬,各類模擬類的方式相對於傳統的面向對象方式來講很是混亂,尤爲是處理當子類繼承父類、子類要調用父類的方法等等需求時。
ES6提供了更接近傳統語言的寫法,引入了Class(類)這個概念,做爲對象的模板。經過class關鍵字,能夠定義類。可是類只是基於原型的面向對象模式的語法糖。
//傳統構造函數 function MathHandle(x,y){ this.x=x; this.y=y; } MathHandle.prototype.add =function(){ return this.x+this.y; }; var m=new MathHandle(1,2); console.log(m.add())
//class語法 class MathHandle { constructor(x,y){ this.x=x; this.y=y; } add(){ return this.x+this.y; } } const m=new MathHandle(1,2); console.log(m.add())
這二者有什麼聯繫?其實這二者本質是同樣的,只不過是語法糖寫法上有區別。所謂語法糖是指計算機語言中添加的某種語法,這種語法對語言的功能沒有影響,可是更方便程序員使用。好比這裏class語法糖讓程序更加簡潔,有更高的可讀性。
typeof MathHandle //"function" MathHandle===MathHandle.prototype.constructor //true
//傳統構造函數繼承 function Animal() { this.eat = function () { alert('Animal eat') } } function Dog() { this.bark = function () { alert('Dog bark') } } Dog.prototype = new Animal()// 綁定原型,實現繼承 var hashiqi = new Dog() hashiqi.bark()//Dog bark hashiqi.eat()//Animal eat
//ES6繼承 class Animal { constructor(name) { this.name = name } eat() { alert(this.name + ' eat') } } class Dog extends Animal { constructor(name) { super(name) // 有extend就必需要有super,它表明父類的構造函數,即Animal中的constructor this.name = name } say() { alert(this.name + ' say') } } const dog = new Dog('哈士奇') dog.say()//哈士奇 say dog.eat()//哈士奇 eat
Class之間能夠經過extends關鍵字實現繼承,這比ES5的經過修改原型鏈實現繼承,要清晰和方便不少。
在JavaScript的世界中,全部代碼都是單線程執行的。因爲這個「缺陷」,致使JavaScript的全部網絡操做,瀏覽器事件,都必須是異步執行。Promise 是異步編程的一種解決方案,比傳統的解決方案(回調函數和事件)更合理和更強大。
ES6中的promise的出現給咱們很好的解決了回調地獄的問題,所謂的回調地獄是指當太多的異步步驟須要一步一步執行,或者一個函數裏有太多的異步操做,這時候就會產生大量嵌套的回調,使代碼嵌套太深而難以閱讀和維護。ES6認識到了這點問題,如今promise的使用,完美解決了這個問題。
一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。Promise對象的狀態改變,只有兩種可能:從pending變爲fulfilled和從pending變爲rejected。promise 對象初始化狀態爲 pending ;當調用resolve(成功),會由pending => fulfilled ;當調用reject(失敗),會由pending => rejected。具體流程見下圖:
function loadImg(src){ const promise=new Promise(function(resolve,reject){ var img=document.createElement('img') img.onload=function(){ resolve(img) } img.onerror=function(){ reject() } img.src=src }) return promise//返回一個promise實例 } var src="http://www.imooc.com/static/img/index/logo_new.png" var result=loadImg(src) result.then(function(img){ console.log(img.width)//resolved(成功)時候的回調函數 },function(){ console.log("failed")//rejected(失敗)時候的回調函數 }) result.then(function(img){ console.log(img.height) })
promise會讓代碼變得更容易維護,像寫同步代碼同樣寫異步代碼,同時業務邏輯也更易懂。
JavaScript 原有的表示「集合」的數據結構,主要是數組(Array)和對象(Object),ES6 又添加了Map和Set。這樣就須要一種統一的接口機制,來處理全部不一樣的數據結構。遍歷器(Iterator)就是這樣一種機制。它是一種接口,爲各類不一樣的數據結構提供統一的訪問機制。任何數據結構只要部署 Iterator 接口,就能夠完成遍歷操做(即依次處理該數據結構的全部成員)。
let arr3 = [1, 2, 'kobe', true]; for(let i of arr3){ console.log(i); // 1 2 kobe true }
let str = 'abcd'; for(let item of str){ console.log(item); // a b c d }
var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]); for (var e of engines) { console.log(e); } // Gecko // Trident // Webkit
ES6 在語言標準的層面上,實現了模塊功能,並且實現得至關簡單,旨在成爲瀏覽器和服務器通用的模塊解決方案。其模塊功能主要由兩個命令構成:export和import。export命令用於規定模塊的對外接口,import命令用於輸入其餘模塊提供的功能。
/** 定義模塊 math.js **/ var basicNum = 0; var add = function (a, b) { return a + b; }; export { basicNum, add }; /** 引用模塊 **/ import { basicNum, add } from './math'; function test(ele) { ele.textContent = add(99 + basicNum); }
如上例所示,使用import命令的時候,用戶須要知道所要加載的變量名或函數名,不然沒法加載。爲了給用戶提供方便,讓他們不用閱讀文檔就能加載模塊,就要用到export default命令,爲模塊指定默認輸出。
// export-default.js export default function () { console.log('foo'); }
上面代碼是一個模塊文件export-default.js,它的默認輸出是一個函數。
其餘模塊加載該模塊時,import命令能夠爲該匿名函數指定任意名字。
// import-default.js import customName from './export-default'; customName(); // 'foo'
上面代碼的import命令,能夠用任意名稱指向export-default.js輸出的方法,這時就不須要知道原模塊輸出的函數名。須要注意的是,這時import命令後面,不使用大括號。
若是以爲文章對你有些許幫助,歡迎在個人GitHub博客點贊和關注,感激涕零!