打開web前端的大門--ECMAScript 6.0入門

注:閱讀本文需要一些前端功底,本文只是介紹es6相對於es5的升級

ECMAScript 6.0 簡介

ECMAScript 6.0(以下簡稱 ES6)是 JavaScript 語言的下一代標準,已經在 2015 年 6 月正式發佈了。它的目標,是使得 JavaScript 語言可以用來編寫複雜的大型應用程序,成為企業級開發語言。

1、ECMAScript 和 JavaScript 的關係

一個常見的問題是,ECMAScript 和 JavaScript 到底是什麼關係?

要講清楚這個問題,需要回顧歷史。1996 年 11 月,JavaScript 的創造者 Netscape 公司,決定將 JavaScript 提交給標準化組織 ECMA,希望這種語言能夠成為國際標準。次年,ECMA 發佈 262 號標準文件(ECMA-262)的第一版,規定了瀏覽器腳本語言的標準,並將這種語言稱為 ECMAScript,這個版本就是 1.0 版。

因此,ECMAScript 和 JavaScript 的關係是,前者是後者的規格,後者是前者的一種實現(另外的 ECMAScript 方言還有 Jscript 和 ActionScript)

2、ES6 與 ECMAScript 2015 的關係

ECMAScript 2015(簡稱 ES2015)這個詞,也是經常可以看到的。它與 ES6 是什麼關係呢?

2011 年,ECMAScript 5.1 版發佈後,就開始制定 6.0 版了。因此,ES6 這個詞的原意,就是指 JavaScript 語言的下一個版本。

ES6 的第一個版本,在 2015 年 6 月發佈,正式名稱是《ECMAScript 2015 標準》(簡稱 ES2015)。

2016 年 6 月,小幅修訂的《ECMAScript 2016 標準》(簡稱 ES2016)如期發佈,這個版本可以看作是 ES6.1 版,因為兩者的差異非常小,基本上是同一個標準。根據計劃,2017 年 6 月發佈 ES2017 標準。

因此,ES6 既是一個歷史名詞,也是一個泛指,含義是 5.1 版以後的 JavaScript 的下一代標準,涵蓋了 ES2015、ES2016、ES2017 等等,而 ES2015 則是正式名稱,特指該年發佈的正式版本的語言標準。本書中提到 ES6 的地方,一般是指 ES2015 標準,但有時也是泛指“下一代 JavaScript 語言”。

二 基礎語法

ES標準中不包含 DOM 和 BOM的定義,只涵蓋基本數據類型、關鍵字、語句、運算符、內建對象、內建函數等通用語法。

// var 聲明的變量沒有局部作用域(es5)
// let 聲明的變量 有局部作用域(es6)
{
var a = 0
let b = 1
}
console.log(a) // 0
console.log(b) // ReferenceError: b is not defined
// var 可以聲明多次 

// let 只能聲明一次
var m = 1
var m = 2
let n = 3
let n = 4
console.log(m) //輸出到控制檯 2
console.log(n) // Identifier 'n' has already been declared
// var 會變量提升
// let 不存在變量提升
console.log(x) //undefined
var x = "apple"
console.log(y) //ReferenceError: y is not defined
let y = "banana"
// 1、聲明之後不允許改變 
const PI = "3.1415926"
PI = 3 // TypeError: Assignment to constant variable.
// 2、一但聲明必須初始化,否則會報錯
const MY_AGE // SyntaxError: Missing initializer in const declaration

解構賦值

解構賦值是對賦值運算符的擴展。

他是一種針對數組或者對象進行模式匹配,然後對其中的變量進行賦值。

在代碼書寫上簡潔且易讀,語義更加清晰明瞭;也方便了複雜對象中數據字段獲取。

//1、數組解構
// 傳統

let a = 1, b = 2, c = 3
console.log(a, b, c)
// ES6
let [x, y, z] = [1, 2, 3]
console.log(x, y, z)
//2、對象解構
let user = {name: 'Helen', age: 18}
// 傳統
var name1 = user.name
var age1 = user.age
console.log(name1, age1)
// ES6
let { name, age } = user//注意:結構的變量必須是user中的屬性
console.log(name, age)

模板字符串

模板字符串相當於加強版的字符串,用反引號 `,除了作為普通字符串,還可以用來定義多行字符串,還可以在字符串中加入變量和表達式。

// 1、多行字符串
let string1 = `Hey,
can you stop angry now?`
console.log(string1)
// Hey,
// can you stop angry now?
// 2、字符串插入變量和表達式。變量名寫在 ${} 中,${} 中可以放入 JavaScript 表達式。
let name = "Mike"
let age = 27
let info = `My Name is ${name},I am ${age+1} years old next year.`
console.log(info)
// My Name is Mike,I am 28 years old next year.
// 3、字符串中調用函數
function f(){
return "have fun!"

}
let string2 = `Game start,${f()}`
console.log(string2); // Game start,have fun!

const age = 12
const name = "Amy"
// 傳統
const person1 = {age: age, name: name}
console.log(person1)
// ES6
const person2 = {age, name}
console.log(person2) //{age: 12, name: "Amy"}

定義方法簡寫

// 傳統
const person1 = {
sayHi:function(){
console.log("Hi")
}
}
person1.sayHi();//"Hi"
// ES6
const person2 = {
sayHi(){
console.log("Hi")
}
}
person2.sayHi() //"Hi"

對象拓展運算符

拓展運算符(...)用於取出參數對象所有可遍歷屬性然後拷貝到當前對象。

// 1、拷貝對象
let person1 = {name: "Amy", age: 15}
let someone = { ...person1 }

console.log(someone) //{name: "Amy", age: 15}
// 2、合併對象
let age = {age: 15}
let name = {name: "Amy"}
let person2 = {...age, ...name}
console.log(person2) //{age: 15, name: "Amy"}

函數的默認參數

function showInfo(name, age = 17) {
console.log(name + "," + age)
}
// 只有在未傳遞參數,或者參數為 undefined 時,才會使用默認參數
// null 值被認為是有效的值傳遞。
showInfo("Amy", 18) // Amy,18
showInfo("Amy", "") // Amy,
showInfo("Amy", null) // Amy, null
showInfo("Amy") // Amy,17
showInfo("Amy", undefined) // Amy,17

箭頭函數

箭頭函數提供了一種更加簡潔的函數書寫方式。基本語法是:

參數 => 函數體
// 傳統
var f1 = function(a){
return a
}
console.log(f1(1))
// ES6
var f2 = a => a
console.log(f2(1))
// 當箭頭函數沒有參數或者有多個參數,要用 () 括起來。

// 當箭頭函數函數體有多行語句,用 {} 包裹起來,表示代碼塊,
// 當只有一行語句,並且需要返回結果時,可以省略 {} , 結果會自動返回。
var f3 = (a,b) => {
let result = a+b
return result
}
console.log(f3(6,2)) // 8
// 前面代碼相當於:
var f4 = (a,b) => a+b

Promise

在JavaScript的世界中,所有代碼都是單線程執行的。由於這個“缺陷”,導致JavaScript的所有網絡操作,瀏覽器事件,都必須是異步執行。

異步執行可以用回調函數實現:

例1、定時器

// 1、timeout的定時器功能使用了回調函數
console.log('before setTimeout()')
setTimeout(()=>{
console.log('Done')
}, 1000) // 1秒鐘後調用callback函數
console.log('after setTimeout()')

例2、ajax

mock/user.json

{
"id": "1",
"username":"helen",
"age":18
}

html頁面引入jquery.js


// 2、ajax功能使用了回調函數
$.get('mock/user.json', (data)=>{

console.log(data)
})

例3、1秒後執行ajax操作

 // 1、timeout的定時器功能使用了回調函數
console.log('before setTimeout()')
setTimeout(() => {
console.log('Done')

// 2、ajax功能使用了回調函數
$.get('mock/user.json', (data) => {

console.log(data)
})

}, 1000); // 1秒鐘後調用callback函數
console.log('after setTimeout()')

例4、1秒後獲取用戶數據,然後根據用戶id獲取用戶登錄日誌

mock/login-log-1.json

{
"items":
[
{
"date":"2018-12-01",
"ip":"10.10.10.10"
},
{
"date":"2018-12-01",
"ip":"10.10.10.10"
}
]
}

回調函數嵌套的噩夢

// 1、1秒後獲取用戶數據
console.log('before setTimeout()')
setTimeout(() => {
console.log('Done')

// 2、獲取用戶數據
$.get('mock/user.json', (data) => {

console.log(data)

// 3、獲取當前用戶的登錄日誌
$.get(`mock/login-log-${data.id}.json`, (data) => {

console.log(data)
})
})

}, 1000) // 1秒鐘後調用callback函數
console.log('after setTimeout()')

Promise是異步編程的一種解決方案。從語法上說,Promise 是一個對象,從它可以獲取異步操作的響應消息。

古人云:“君子一諾千金”,這種“承諾將來會執行”的對象在JavaScript中稱為Promise對象。



有錯誤處理的promise案例



也可以使用catch處理失敗

.then((data)=>{//成功

})
.catch(()=>{//處理失敗:then方法的第二個參數是失敗的回調
console.log('出錯啦!')
})


分享到:


相關文章: