筆者這兩天在整理react知識(shí)點(diǎn)的時(shí)候斟叼,順便對(duì)es6的基礎(chǔ)知識(shí)也進(jìn)行了一些整理斯嚎,其實(shí)es6出來(lái)已經(jīng)很久了,也不算是一個(gè)新的技術(shù)了俘陷,現(xiàn)在也已經(jīng)很普及了,所以是時(shí)候?qū)⑺莆掌饋?lái)了观谦。
一拉盾,es6是什么以及為什么要學(xué)習(xí)它
ECMAScript 6(以下簡(jiǎn)稱(chēng)ES6)是JavaScript語(yǔ)言的下一代標(biāo)準(zhǔn),已經(jīng)在2015年6月正式發(fā)布了豁状。它的目標(biāo)捉偏,是使得JavaScript語(yǔ)言可以用來(lái)編寫(xiě)復(fù)雜的大型應(yīng)用程序,成為企業(yè)級(jí)開(kāi)發(fā)語(yǔ)言替蔬。
標(biāo)準(zhǔn)的制定者有計(jì)劃告私,以后每年發(fā)布一次標(biāo)準(zhǔn),使用年份作為標(biāo)準(zhǔn)的版本承桥。因?yàn)楫?dāng)前版本的ES6是在2015年發(fā)布的驻粟,所以又稱(chēng)ECMAScript 2015。也就是說(shuō)凶异,ES6就是ES2015蜀撑,下一年應(yīng)該會(huì)發(fā)布小幅修訂的ES2016。
雖然現(xiàn)在的瀏覽器還不能支持es6剩彬,但是我們能通過(guò)babel語(yǔ)法轉(zhuǎn)化器酷麦,將es6轉(zhuǎn)化為能被大多數(shù)瀏覽器能夠支持的es5。
流行的庫(kù)基本都基于es6構(gòu)建喉恋,React默認(rèn)使用es6新語(yǔ)法開(kāi)發(fā)沃饶,現(xiàn)在React16.0中母廷。
es6出來(lái)已經(jīng)很久了,筆認(rèn)為它已經(jīng)算不上是一個(gè)新技術(shù)糊肤,而且現(xiàn)在已經(jīng)很普及琴昆,將來(lái)必定也是一個(gè)趨勢(shì),而且現(xiàn)在前端這個(gè)領(lǐng)域的技術(shù)更新迭代特別的快馆揉,因此掌握es6顯得尤為重要业舍。
二,環(huán)境準(zhǔn)備升酣,使用react官方推薦的腳手架create-react-app
安裝nodejs
npm install -g create-react-app 安裝腳手架
npm install -g create-react-app
- create-react-app es6-demo 創(chuàng)建react項(xiàng)目
cd Desktop // 進(jìn)入桌面
create-react-app es6-demo // 用腳手架生成es6-demo
三舷暮,es6里都有些什么
塊級(jí)作用域,字符串噩茄,函數(shù)
對(duì)象擴(kuò)展下面,解構(gòu)
類(lèi),模塊化
1绩聘,作用域:let與const
定義變量使用let代替var诸狭,塊級(jí)作用域
Const定義不可修改的變量
// let:塊級(jí)作用域
{
var a1 = 'darrell1';
let a2 = 'darrell2'
}
console.log(a1); // darrell1
console.log(a2); // 'a2' is not defined
// const:基本類(lèi)型
const a3 = 'darrell3'
a3 = 'darrell4'
console.log(a3); // "a3" is read-only
const a = []; // 如果是引用類(lèi)型的話(huà),往里面添加值是沒(méi)問(wèn)題的君纫,但是改變指向后則會(huì)報(bào)錯(cuò)
a.push('apple');
a.push('egg');
console.log(a); // ["apple", "egg"]
2驯遇,字符串:模板字符串
使用反引號(hào),直接寫(xiě)變量
多行字符串
告別+拼接字符串
let name='imooc'
// es5
console.log('hello '+name+'! \n you are funny!')
// es6 after
console.log(`hello ${name}!
you are funny!`) // 換行不需要加\n,直接換行就行
3蓄髓,函數(shù)擴(kuò)展:ES6中函數(shù)的用法
參數(shù)有默認(rèn)值
箭頭函數(shù)
展開(kāi)運(yùn)算符
// 帶默認(rèn)參數(shù)的箭頭函數(shù)
let hello = (name='world')=>{
console.log(`hello ${name}`)
}
// 直接返回值的箭頭函數(shù)
let cal = num=>num*2
// 多個(gè)參數(shù)
let cal1 = (num1, num2)=>num1*num2
hello() // hello world
hello('darrell') // hello darrell
console.log(cal(5)) // 10
console.log(cal1(5, 6)) // 30
let arr = [6, 7]
console.log(cal1(...arr)) // ...解構(gòu)叉庐,輸出 42
4,對(duì)象擴(kuò)展:Object擴(kuò)展
Object.keys会喝、values陡叠、entries
對(duì)象方法簡(jiǎn)寫(xiě),計(jì)算屬性
展開(kāi)運(yùn)算符(不是ES6標(biāo)準(zhǔn)肢执,但是babel也支持)
const name = 'imooc'
// es5
const obj = {
name: name,
site:'imooc.com',
sayHello: function(){
console.log('hello world!')
}
}
console.log(obj)
obj.sayHello()
//es6:
//在對(duì)象里面添加跟變量名一樣的屬性址枉阵,并且屬性的值就是變量的屬性址。就可以直接簡(jiǎn)寫(xiě)成下面這樣,函數(shù)也可以簡(jiǎn)寫(xiě)
const obj = {
name,
site:'imooc.com',
sayHello(){
console.log('hello world!')
}
}
console.log(obj)
obj.sayHello()
5预茄,解構(gòu)賦值兴溜,函數(shù)也可以多返回值
數(shù)組結(jié)構(gòu)
對(duì)象解構(gòu)
const [name, age] = ['imooc', '20']
const {title,job} = {title:'React開(kāi)發(fā)App', job:'IT'}
console.log(name,age) // imooc,20
console.log(title,job) // React開(kāi)發(fā)App, IT
6,類(lèi):提供class的語(yǔ)法糖
是prototype的語(yǔ)法糖
Extends繼承
Constructor構(gòu)造函數(shù)
class MyApp{
constructor(age) {
this.name='darrell'
this.age = age
} //用這個(gè)類(lèi)實(shí)例化一個(gè)對(duì)象是耻陕,會(huì)最先執(zhí)行這個(gè)構(gòu)造器
sayHello(){
console.log(`hello ${this.name}, I am ${this.age} years old`) //模版字符串
}
}
let app = new MyApp(18)
app.sayHello() // 輸出的為:hello darrell, I am 18 years old
7拙徽,新的數(shù)據(jù)結(jié)構(gòu):ES6中新出現(xiàn)的數(shù)據(jù)結(jié)構(gòu)
Set,元素不可重合
Map
Symbol
// Set:不能有重復(fù)的內(nèi)容
let desserts = new Set(['tomao','peats','egg']);
desserts.add('toma');
console.log(desserts); // ['tomao','peats','egg','toma']
console.log(desserts.size); 4
console.log(desserts.has('tomao')); // true
desserts.delete('toma');
console.log(desserts) // ['tomao','peats','egg']
desserts.clear(); // []
這幾個(gè)是es6中新出現(xiàn)的數(shù)據(jù)結(jié)構(gòu)诗宣,我上面就拿set舉了一個(gè)簡(jiǎn)單的例子膘怕。具體的大家可以去參考考阮一峰老師的ECMAScript 6 入門(mén)中關(guān)于這幾個(gè)概念的說(shuō)明哦。
8召庞,模塊化:ES6中自帶了模塊化機(jī)制岛心,告別seajs和require.js
Import,import{}
Emport,Export default
Node現(xiàn)在還不支持来破,還需要require來(lái)加載文件
// module1.js
let fruit = 'apple';
let dessert = 'cake';
let dinner = (fruit,dessert) => {
console.log(`今天的晚餐是${fruit}和${dessert}`);
}
export {fruit,dessert};
export default dinner; // 導(dǎo)出默認(rèn)的函數(shù)
//module2.js
import dinner from './module1.js'; //這個(gè)是拿到module1.js默認(rèn)導(dǎo)出的dinner函數(shù)
dinner('apple','egg'); // 今天的晚餐是apple和egg
import * as chef from './module1.js'; // 將module1種所有的export都導(dǎo)出重命名為chef
chef.default('apple','egg');// 今天的晚餐是apple和egg,默認(rèn)導(dǎo)出的是放在chef的defalut里
chef.default(chef.fruit,chef.dessert); // 今天的晚餐是apple和cake
9,還有一些特性忘古,雖然不在ES6的范圍讳癌,其他的特性,但是也被babel支持存皂,普遍被大家接受和使用(需要安裝插件)。不過(guò)這些對(duì)于初學(xué)者來(lái)說(shuō)逢艘,這些暫時(shí)還不需要全部掌握旦袋。
- Async await
處理異步的方法,非常的簡(jiǎn)單優(yōu)雅,具體大家可以參考阮一峰老師的這篇文章它改,async 函數(shù)的含義和用法,
- Promise
new Promise((resolve) => {
setTimeout(function(){
resolve()
}, 3000);
}).then(() => {
console.log('promise 成功');
});
上面是一個(gè)簡(jiǎn)單的例子疤孕,我new了一個(gè)promise對(duì)象,讓他在三秒之后可以輸出promise 成功央拖,具體的操作大家可以查看祭阀,具體的Promise大家可以參考阮一峰老師的ECMAScript 6 入門(mén)這本書(shū)中對(duì)于Promise的講解,講的很好鲜戒。
其實(shí)promise更多的是用來(lái)獲取數(shù)據(jù)专控,比如我們?cè)趓eact項(xiàng)目中,會(huì)通過(guò)fetch發(fā)送異步請(qǐng)求遏餐,其實(shí)fetch返回的就是一個(gè)promise對(duì)象伦腐,所以我們一直.then()
- 迭代器(Iterators)和生成器(Generators)
// 自己實(shí)現(xiàn)的一個(gè)簡(jiǎn)單版的迭代器
function chef(foods) {
let i = 0;
return {
next(){
let done = (i >= foods.length);
let value = !done ? foods[i++] : undefined;
return {
value: value,
done:done
}
}
}
}
let anghao = chef(['tomato','egg']);
console.log(anghao.next()); // {value: "tomato", done: false}
console.log(anghao.next()); // {value: "egg", done: false}
console.log(anghao.next()); // {value: undefined, done: true}
//es6 的 Generators
function* chef(foods) {
for(var i = 0 ;i< foods.length;i++) {
yield foods[i]
}
}
//第二種
let wanghao = chef(['tomato','egg']);
console.log(wanghao.next()); // {value: "tomato", done: false}
console.log(wanghao.next()); // {value: "egg", done: false}
console.log(wanghao.next()); // {value: undefined, done: true}
以上是簡(jiǎn)單的迭代器與生成器的例子,筆者最近在學(xué)習(xí)阿里的dva
的redux
框架失都,其中他處理異步數(shù)據(jù)流的時(shí)候使用了redux-saga
,里面有用到生成器柏蘑。不過(guò)對(duì)于初學(xué)者來(lái)說(shuō),這些暫時(shí)還不需要掌握粹庞。
四咳焚,結(jié)語(yǔ)
個(gè)人感覺(jué)學(xué)習(xí)的最好的方法就是去實(shí)踐,先把一些es6的基礎(chǔ)的運(yùn)用到你日常的工作當(dāng)中去庞溜,將一些原來(lái)的es5的方法改寫(xiě)為es6的方法革半。能幫助我們快速的理解es6的語(yǔ)法。
如在面試過(guò)程中我們最常碰到了一道面試題
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(function() { console.log(i) })
}
funcs.forEach(function(func) {
func()
})
這個(gè)面試題已經(jīng)是考作用域的一道經(jīng)典題目了流码,答案是輸出10個(gè)10督惰。
在es5中我們?cè)撛趺醋觯隙ㄊ抢瞄]包來(lái)解決問(wèn)題旅掂,下圖是一個(gè)立即執(zhí)行函數(shù)赏胚。
// ES5告訴我們可以利用閉包解決這個(gè)問(wèn)題
var funcs = []
for (var i = 0; i < 10; i++) {
func.push((function(value) {
return function() {
console.log(value)
}
}(i)))
}
這樣我們便能得到0-9,依次輸出商虐。
但是當(dāng)我們有了let
之后,我們可以這樣寫(xiě)
// es6
for (let i = 0; i < 10; i++) {
func.push(function() {
console.log(i)
})
}
我們也能得到相同的結(jié)果觉阅,但是相比于es5的代碼崖疤,是不是更加簡(jiǎn)潔呢。
但是這里我想講的是典勇,雖然es6更加簡(jiǎn)潔了劫哼,但是懂閉包這個(gè)概念,可以幫我們更好的理解js的作用域割笙,上下文的關(guān)系权烧。
除了上面這個(gè)概念,還比如說(shuō)函數(shù)中的this的指向問(wèn)題伤溉,箭頭函數(shù)的this是指向函數(shù)本身的般码,而es5中的函數(shù)則不一定,有些是指向window的乱顾。
es6還有很多值得我們?nèi)ネ娴闹R(shí)點(diǎn)板祝,希望我的這邊文章能給大家?guī)?lái)一點(diǎn)點(diǎn)啟發(fā)。