let和const相似於javascript中的var的使用,都是用來聲明變量的,只是都存在各自的特殊用法。javascript
在javascript中只有全局做用域和函數做用域,例如:java
var name = 'one';//全局變量 while(true){ name = 'two'; console.log(name);//two,內層變量覆蓋了外層變量 break; } console.log(name);//two,
不出意料,兩次輸出結果都是two。es6
而ES6帶來的一個新特性:編程
使用let聲明的變量,只做用於使用了let命令的代碼塊:數組
var name = 'one';//全局變量 while(true){ let name = 'two'; console.log(name);//two, break; } console.log(name);//one
const PI = Math.PI; console.log(PI); //3.141592653589793 PI = 666; //報錯Module build failed: SyntaxError: "PI" is read-only
es6模板字符簡直是開發者的福音,解決了ES5在字符串功能上的痛點。promise
基本的字符串格式化,將表達式嵌入字符串中進行拼接。用${}來界定。例如:數據結構
//es5 var name = 'Archer' console.log('hello' + name) //es6 const name = 'Archer' console.log(`hello ${name}`) //hello Archer
在ES5時咱們經過反斜槓()來作多行字符串或者字符串一行行拼接。ES6反引號(``)直接搞定。異步
// es5 var msg = "Hi \ Archer! " // es6 const template = `<div> <span>hello Archer</span> </div>`
對於字符串es6固然也提供了不少厲害的方法,列舉幾個經常使用的:異步編程
// includes:判斷是否包含而後直接返回布爾值 let str = 'hahay' console.log(str.includes('y')) // true // repeat: 獲取字符串重複n次 let s = 'ha' console.log(s.repeat(3)) // 'hahaha'
ES6頗有意思的一部分就是函數的快捷寫法,也就是箭頭函數,箭頭函數最直觀的三個特色:函數
let arr = [1,2,3]; arr.map(item => item + 1) //等同於 arr.map(function(item){ return item + 1 })
當函數有且僅有一個參數的時候,是能夠省略掉(),當函數返回有且僅有一個表達式的時候能夠省略{};例如:
//參數name就沒有括號 var people = name => 'hello' + name
ES6 以前,不能直接爲函數的參數指定默認值,只能採用變通的方法。例如:
function log(x, y) { y = y || 'Archer'; console.log(x, y); } log('Hello') // Hello Archer log('Hello', 'China') // Hello China log('Hello', '') // Hello Archer
上面代碼檢查函數log的參數y有沒有賦值,若是沒有,則指定默認值爲Archer。這種寫法的缺點在於,若是參數y賦值了,可是對應的布爾值爲false,則該賦值不起做用。就像上面代碼的最後一行,參數y等於空字符,結果被改成默認值。
如今 ES6 容許爲函數的參數設置默認值,即直接寫在參數定義的後面,爲賦值提供了簡便的方法。例如:
function log(x, y = 'Archer') { console.log(x, y); } log('Hello') // Hello Archer log('Hello', 'China') // Hello China log('Hello', '') // Hello
能夠看到,ES6 的寫法比 ES5 簡潔許多,並且很是天然。下面是另外一個例子。
function Point(x = 0, y = 0) { this.x = x; this.y = y; } const p = new Point(); p // { x: 0, y: 0 }
...展開運算符,有兩種層面
let a = [1,2,3]; let b = [0, ...a, 4]; // [0,1,2,3,4] let obj = { a: 1, b: 2 }; let obj2 = { ...obj, c: 3 }; // { a:1, b:2, c:3 } let obj3 = { ...obj, a: 3 }; // { a:3, b:2 }
let a = [1,2,3]; let [b, ...c] = a; b; // 1 c; // [2,3] // 也能夠 let a = [1,2,3]; let [b, ...[c,d,e]] = a; b; // 1 c; // 2 d; // 3 e; // undefined // 也能夠 function test(a, ...rest){ console.log(a); // 1 console.log(rest); // [2,3] } test(1,2,3)
對象初始化簡寫
ES5咱們對於對象都是以鍵值對的形式書寫,是有可能出現鍵值對重名的。例如:
function people(name, age) { return { name: name, age: age }; }
鍵值對重名,ES6能夠簡寫以下:
function people(name, age) { return { name, age }; }
ES6 一樣改進了爲對象字面量方法賦值的語法。ES5爲對象添加方法:
const people = { name: 'lux', getName: function() { console.log(this.name) } }
ES6經過省略冒號與 function 關鍵字,將這個語法變得更簡潔:
const people = { name: 'lux', getName () { console.log(this.name) } }
ES6 對象提供了Object.assign()這個方法來實現淺複製。Object.assign()能夠把任意多個源對象自身可枚舉的屬性拷貝給目標對象,而後返回目標對象。第一參數即爲目標對象。在實際項目中,咱們爲了避免改變源對象。通常會把目標對象傳爲{}。
const obj = Object.assign({}, objA, objB)
數組和對象是JS中最經常使用也是最重要表示形式。爲了簡化提取信息,ES6新增瞭解構,這是將一個數據結構分解爲更小的部分的過程。
ES5咱們提取對象中的信息形式以下:
const people = { name: 'Archer', age: 28 } const name = people.name const age = people.age console.log(name + ' --- ' + age) //"Archer --- 28"
在ES6以前咱們就是這樣獲取對象信息的,一個一個獲取。如今,解構能讓咱們從對象或者數組裏取出數據存爲變量。例如:
//對象 const people = { name: 'Archer', age: 28 } const { name, age } = people console.log(`${name} --- ${age}`) //數組 const color = ['red', 'blue'] const [first, second] = color console.log(first) //'red' console.log(second) //'blue'
import導入模塊、export導出模塊
//所有導入 import people from './example' //有一種特殊狀況,即容許你將整個模塊看成單一對象進行導入 //該模塊的全部導出都會做爲對象的屬性存在 import * as example from "./example.js" console.log(example.name) console.log(example.age) console.log(example.getName()) //導入部分 import {name, age} from './example' // 導出默認, 有且只有一個默認 export default App // 部分導出 export class App extend Component {};
導入的時候有沒有大括號的區別是什麼。下面是我在工做中的總結:
在promise以前代碼過多的回調或者嵌套,可讀性差、耦合度高、擴展性低。經過Promise機制,扁平化的代碼機構,大大提升了代碼可讀性;用同步編程的方式來編寫異步代碼,保存線性的代碼邏輯,極大的下降了代碼耦合性而提升了程序的可擴展性。
Promise對象有如下兩個特色:
說白了就是用同步的方式去寫異步代碼,下面代碼創造了一個Promise實例:
const promise = new Promise(function(resolve, reject) { if (/* 異步操做成功 */){ resolve(value); } else { reject(error); } });
Promise構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolve和reject。它們是兩個函數,由 JavaScript 引擎提供,不用本身部署。
resolve函數的做用是,將Promise對象的狀態從「未完成」變爲「成功」(即從 pending 變爲 resolved),在異步操做成功時調用,並將異步操做的結果,做爲參數傳遞出去;reject函數的做用是,將Promise對象的狀態從「未完成」變爲「失敗」(即從 pending 變爲 rejected),在異步操做失敗時調用,並將異步操做報出的錯誤,做爲參數傳遞出去。
Promise實例生成之後,能夠用then方法分別指定resolved狀態和rejected狀態的回調函數。
promise.then(function(value) { // success }, function(error) { // failure });
下面是一個Promise對象的簡單例子,timeout方法返回一個Promise實例,表示一段時間之後纔會發生的結果。過了指定的時間(ms參數)之後,Promise實例的狀態變爲resolved,就會觸發then方法綁定的回調函數。:
function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(resolve, ms, 'done'); }); } timeout(100).then((value) => { console.log(value); });
生成器( generator)是能返回一個迭代器的函數。生成器函數也是一種函數,最直觀的表現就是比普通的function多了個星號*,在其函數體內可使用yield關鍵字,有意思的是函數會在每一個yield後暫停。
這裏生活中有一個比較形象的例子。我們到銀行辦理業務時候都得向大廳的機器取一張排隊號。你拿到你的排隊號,機器並不會自動爲你再出下一張票。也就是說取票機「暫停」住了,直到下一我的再次喚起纔會繼續吐票。
說說迭代器。當你調用一個generator時,它將返回一個迭代器對象。這個迭代器對象擁有一個叫作next的方法來幫助你重啓generator函數並獲得下一個值。next方法不只返回值,它返回的對象具備兩個屬性:done和value。value是你得到的值,done用來代表你的generator是否已經中止提供值。繼續用剛剛取票的例子,每張排隊號就是這裏的value,打印票的紙是否用完就這是這裏的done。
// 生成器 function *createIterator() { yield 1; yield 2; yield 3; } // 生成器能像正規函數那樣被調用,但會返回一個迭代器 let iterator = createIterator(); console.log(iterator.next().value); // 1 console.log(iterator.next().value); // 2 console.log(iterator.next().value); // 3
那生成器和迭代器又有什麼用處呢?
圍繞着生成器的許多興奮點都與異步編程直接相關。異步調用對於咱們來講是很困難的事,咱們的函數並不會等待異步調用完再執行,你可能會想到用回調函數,(固然還有其餘方案好比Promise好比Async/await)。
生成器可讓咱們的代碼進行等待。就不用嵌套的回調函數。使用generator能夠確保當異步調用在咱們的generator函數運行一下行代碼以前完成時暫停函數的執行。
那麼問題來了,我們也不能手動一直調用next()方法,你須要一個可以調用生成器並啓動迭代器的方法。就像這樣子的:
function run(taskDef) { //taskDef即一個生成器函數 // 建立迭代器,讓它在別處可用 let task = taskDef(); // 啓動任務 let result = task.next(); // 遞歸使用函數來保持對 next() 的調用 function step() { // 若是還有更多要作的 if (!result.done) { result = task.next(); step(); } } // 開始處理過程 step(); }
生成器與迭代器最有趣、最使人激動的方面,或許就是可建立外觀清晰的異步操做代碼。你沒必要處處使用回調函數,而是能夠創建貌似同步的代碼,但實際上卻使用 yield 來等待異步操做結束。
ES6的特性遠不止於此,但對於咱們平常的開發開說,這已是夠夠的了,還有不少有意思的方法。好比for of,Iterator...等等。
來都來了點一下贊吧,你的贊是對我最大的鼓勵^_^
但願更全面瞭解es6夥伴們能夠去看阮一峯所著的電子書ECMAScript 6入門