ES6新特性整理

歡迎訪問我的博客https://qqqww.com/叮贩,祝碼農同胞們早日走上人生巔峰,迎娶白富美~~~

由于沒寫目錄板鬓,移步https://blog.csdn.net/weixin_43307658/article/details/86698281體驗更好

1 Babel 轉碼

請移步我的另一篇博客ES6-Babel轉碼

2 聲明變量

ES6 中常用 letconst 來聲明變量肴甸,下面介紹 letconst

2.1 let

ES6 新增了let命令,用來聲明變量腿时。它的用法類似于var,但是所聲明的變量饭宾,只在let命令所在的代碼塊內有效

2.1.1 引入 let 的好處

我們在 ES5 中使用 var 來聲明變量批糟,但是var變量提升往往會帶來一些問題:

// 使用 var
console.log(a) // 輸出 undefined
var a = 1

// 使用 let
console.log(b) // 輸出 ReferenceError
let b = 1

一般我們認為應該先聲明變量再使用,但是這里使用var聲明的變量卻能提前使用看铆,而不報錯徽鼎,本身在邏輯性上可能會覺得不太好,但是還沒有看到具體會引起什么錯誤弹惦,那么再看下面的代碼:

var a = new Date() // Tue Jan 29 2019 20:31:15 GMT+0800 (中國標準時間)
function fn () {
    cosole.log(a) 
    if (false) {
        a = 'hello'
        console.log(a)
    }
}
fn() // undefined

上述代碼由于if代碼塊使用內層的變量否淤,外面的使用外層的變量,看似互不影響棠隐,但是由于var存在變量提升石抡,導致內層的a覆蓋了外層的a,甚至有可能將局部變量提升為全局變量助泽,以后有可能引起內存泄漏

所以引入let啰扛,let聲明的變量有自己獨立的作用域塊,let聲明的變量只在let所在的塊內起作用嗡贺,不再受外部影響隐解,形成暫時性死區(qū),有效防止變量提升問題

暫時性死區(qū):在代碼塊內暑刃,使用let命令聲明變量之前厢漩,該變量都是不可用的

我們將上述代碼中的 var 換為 let 看看

let a = new Date() // Tue Jan 29 2019 20:31:15 GMT+0800 (中國標準時間)
function fn () {
    cosole.log(a) 
    if (false) {
        a = 'hello'
        console.log(a)
    }
}
fn() // Tue Jan 29 2019 20:31:15 GMT+0800 (中國標準時間)

這時候就不存在變量提升的問題了

2.1.2 let 規(guī)則

使用let聲明的變量可以重新賦值,但是不能在同一作用域內重新聲明

2.2 const

constlet 引入的好處基本一樣,但是為什么還要引入呢岩臣?看看下面的 const 規(guī)則:

使用const聲明的變量必須賦值初始化,但是不能在同一作用域類重新聲明也無法重新賦值

它們的區(qū)別就在于規(guī)則,其他幾乎一模一樣

3 模板字面量

ES6中的模板字面量就是通過一種更加簡便的方法去拼接字符串宵膨,在以前我們常通過+或者concat()等方法去拼接字符串

const dog1 = {
    name: 'dahuang',
    age: 10
}
const dog2 = {
    name: 'xiaohei',
    age: 10
}
let mes = dog1.name + 'and' + dog2.name + 'are dog'

下面用模板字面量去拼接字符串

let mes = `${dog1.name} and ${dog2.name} are dog`

一對反引號搞定

4 解構賦值

ES6 允許按照一定模式架谎,從數(shù)組和對象中提取值,對變量進行賦值辟躏,這被稱為解構(Destructuring)

以前為變量賦值谷扣,只能直接指定值,下面來自阮一峰老師的文檔里的一個小例子

let a = 1
let b = 2
let c = 3

ES6 允許下面這樣

let [a, b, c] = [1, 2, 3]

上面代碼表示,可以從數(shù)組中提取值会涎,按照對應位置裹匙,對變量賦值

解構賦值的規(guī)則是,只要等號右邊的值不是對象或數(shù)組末秃,就先將其轉為對象概页。由于undefinednull無法轉為對象,所以對它們進行解構賦值练慕,都會報錯

let { prop: x } = undefined // TypeError
let { prop: y } = null // TypeError

4.1 數(shù)組的解構賦值

const arr = [1, 2, 3]
const [a, b, c] = arr
console.log(a, b, c) // 1, 2, 3

4.2 對象的解構賦值

let { foo1, foo2 } = { foo1: 'a', foo2: 'b' }
// foo1 => 'a'  foo2 => 'b'

對象字面量的寫法

let name = 'dahuang'
let color = 'yellow'
const dog = {name, color}
console.log(dog)

4.3 字符串的解構賦值

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

4.4 數(shù)值和布爾值的解構賦值

解構賦值時惰匙,如果等號右邊是數(shù)值和布爾值,則會先轉為對象

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

上面代碼中铃将,數(shù)值和布爾值的包裝對象都有toString屬性项鬼,因此變量s都能取到值

4.5 函數(shù)參數(shù)的解構賦值

function add([x, y]){
  return x + y
}

add([1, 2]) // 3

函數(shù)add的參數(shù)表面上是一個數(shù)組,但在傳入?yún)?shù)的那一刻劲阎,數(shù)組參數(shù)就被解構成變量xy

我們用Babel在線轉換工具把上述ES6代碼轉化為ES5代碼看看绘盟,實際上就是講作為參數(shù)的數(shù)組分別結構成了xy再返回他們的和

"use strict";

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

function add(_ref) {
  var _ref2 = _slicedToArray(_ref, 2),
      x = _ref2[0],
      y = _ref2[1];

  return x + y;
}

add([1, 2]); // 3

4.6 其他

當然對于解構賦值還有很多新玩法,例如可以添加默認值悯仙,這里阮一峰老師寫的很詳細奥此,請移步ES6標準入門

5 for...of

for...of 語句創(chuàng)建一個循環(huán)來迭代可迭代的對象跋核。在 ES6 中引入的 for...of 循環(huán)样勃,以替代 for...inforEach() 霞赫,并支持新的迭代協(xié)議空免。for...of 允許你遍歷 Arrays(數(shù)組), Strings(字符串), Maps(映射), Sets(集合)等可迭代的數(shù)據(jù)結構

我們先來看看以前的方法

for 循環(huán)

let arr = [1, 2, 3, 4, 5, 6]
for (let i = 1; i < arr.length; i++) {
    console.log(arr[i])
}

缺點:需要跟蹤計時器和退出條件

雖然 for 循環(huán)在循環(huán)數(shù)組時的確具有優(yōu)勢碎乃,但是某些數(shù)據(jù)結構不是數(shù)組杨耙,因此并非始終適合使用 loop 循環(huán)

for...in循環(huán)

let arr = [1, 2, 3, 4, 5, 6]
for (const index in arr) {
    console.log(arr[index])
}

缺點for...in 循環(huán)循環(huán)訪問所有可枚舉的屬性晋辆,意味著如果向數(shù)組的原型中添加任何其他屬性或者方法穿稳,這些屬性或方法也會出現(xiàn)在循環(huán)中茴她,這就無意間浪費了資源

forEach()循環(huán)

數(shù)組方法寻拂,只用于數(shù)組中,局限性大

for...of循環(huán)

const arrs = [1, 2, 3, 4, 5, 6]
for (const arr of arrs) {
    console.log(arr)
}
// 可忽略索引

而且可以隨時退出或者停止for...of循環(huán)

const arrs = [1, 2, 3, 4, 5, 6]
for (const arr of arrs) {
    if (arr % 2 === 0) {
        continue
    }
    console.log(arr)
}

且不用擔心向對象中添加新的屬性丈牢。for...of 循環(huán)將只循環(huán)訪問對象中的值

6 展開運算符

ES6中提供了展開運算符為...

const dogs = ['dahuang', 'xiaohei', 'xiaobai']
console.log(...dogs) // dahuang xiaohei xiaobai

6.1 數(shù)組拼合

const dogs = ['dahuang', 'xiaohei', 'xiaobai']
const peoples = ['xiaoming', 'zhangsan', 'zhaosi', 'wangwu'] 
const animals = [...dogs, ...peoples] 
console.log(animals) 
// ['dahuang', 'xiaohei', 'xiaobai', 'xiaoming', 'zhangsan', 'zhaosi', 'wangwu']

這實際上已經(jīng)完成了以前拼合數(shù)組使用的concat()的功能

6.2 剩余參數(shù)

使用展開運算符將數(shù)組展開為多個元素, 使用剩余參數(shù)可以將多個元素綁定到一個數(shù)組中

  1. 將變量賦數(shù)組值
const goods = [20, 200, 'pen', 'book', 'ruler']
const [price, totalCount, ...studyGoods] = goods
console.log(price, totalCount, studyGoods) 
// 前兩個參數(shù)對應前兩個祭钉,后面的作為數(shù)組傳入 studyGoods
  1. 可變剩余參數(shù)作為函數(shù)形參使用
function add (...numbers) {
    let sum = 0
    for (const number of numbers) {
        sum += number
    }
    return sum
}

6.3 ES6 箭頭函數(shù)

箭頭函數(shù)是 ES6中的一大亮點 ,下面看簡單的 ES5 中的函數(shù) 和 ES6 中的箭頭函數(shù)

ES5 中的函數(shù)

var fn = function () { console.log('我是es5') }

ES6中的箭頭函數(shù)

const fn = () => { console.log('我是es6') }
// 等價于
const fn = () => console.log('我是es6')

就是講ES5中的function()去掉己沛,變成() =>慌核,且當函數(shù)體只有一句程序的時候,大括號也能省略

比較ES5中的函數(shù)和箭頭函數(shù)

  1. 前者可以使函數(shù)聲明或者函數(shù)表達式申尼,但是后者只能是函數(shù)表達式垮卓,因此只在表達式有效的時候才能使用
  2. 什么是表達式有效時?
    1. 存儲在變量中
    2. 當做參數(shù)傳遞給函數(shù)
    3. 存儲在對象屬性中

6.4 存儲在變量中的時候

其實上面的例子也說明了這點师幕,下面再舉兩個簡單的例子

const fn = numbers => `The pen are ${ numbers }`
// 調用
fn(200) // The pen are 200
const people = (name, age) => console.log(`${ name } is ${ age } years old`)

6.5 當做參數(shù)傳遞給函數(shù)的時候

將函數(shù)表達式當做參數(shù)傳遞給map函數(shù)粟按,一般就是用于需要回調的函數(shù)

const people = ['zhangsan', 'zhaosi', 'wangwu'].map(name => name.toUpperCase())

6.6 存儲在對象屬性中的時候

const people = {
    name: 'zhangsan',
    age: 10,
    say: () => console.log('hello')
}
console.dir(people.say) // say() 方法

6.7 箭頭函數(shù)與this

對于普通函數(shù),this的值基于函數(shù)如何被調用, 對于箭頭函數(shù),this的值基于函數(shù)周圍的上下文, 換句話說,this的值和函數(shù)外面的this的值是一樣的

6.7.1 普通情況下的this

  1. new對象,
const time = new Date() // 此時的this是Date()構造函數(shù)的實例對象
  1. 上下文
window.setTimeout() // 函數(shù)`setTimeout()`是對象`window`下的方法,此時this指向window
  1. 指定的對象
const arr = Array.prototype.slice.call(arr1)
const arr = Array.prototype.slice.apply(arr1)
// call 或者 apply 第一個參數(shù)設置 this 指向灭将,所以此時 this 指向 arr1

此外疼鸟,this 指向還有很多其他的講究,詳細見You-Dont-Know-JS

6.7.2 箭頭函數(shù)與this

我們首先來看一個例子

Array.prototype.init = function () {
    console.log(this)
    setTimeout(function () {
        console.log(this)
    }, 1000)
}

這時候兩次打印出來的 this 一樣嗎庙曙?執(zhí)行Array.prototype.init()打印結果出來看一下:

很顯然空镜,第一個打印出了Array構造函數(shù),第二個是Window矾利,因為setTimeout()Window的方法姑裂,所以會改變this指向,那么使用箭頭函數(shù)看看

Array.prototype.init = function () {
    console.log(this)
    setTimeout( () => console.log(this), 1000)
}
Array.prototype.init()

這次就打印出了兩個Array男旗,this指向沒有發(fā)生變化

6.7.3 應用場景

  1. 一些事件綁定之后需要操作原事件對象時防止this改變
  2. 用到一些構造函數(shù)的方法的時候舶斧,防止該構造函數(shù)的this被改變
  3. 等等......

7 Symbol

請移步我的另一篇博客ES6中的Symbol

8 class類

請移步我的另一篇博客ES6中的class關鍵字

9 Promise

請移步我的另一篇博客node-讀取文件方法封裝

10 Proxy

攔截代理,即在目標對象外層包裹一層攔截察皇,外接對對象的訪問都必須要先通過這層攔截茴厉,有點過濾的感覺,也有點像“門衛(wèi)”什荣,小區(qū)進門之前都要先過“門衛(wèi)”

10.1 語法

var proxy = new Proxy(target, handler)

10.2 參數(shù)

  1. target:對象類型矾缓,表示需要被攔截的對象
  2. handler:對象類型,表示需要對這個對象target要做的攔截操作

10.3 例子

var proxy = new Proxy({}, {
  get: function(target, property) {
    return 35;
  }
});

proxy.time // 35
proxy.name // 35
proxy.title // 35

如果handler沒有設置任何攔截稻爬,那就等同于直接通向原對象

var target = {};
var handler = {};
var proxy = new Proxy(target, handler);
proxy.a = 'b';
target.a // "b"

11 Module

請移步我的另一篇博客ES6中Module語法與加載實現(xiàn)

12 參考文章

本文參考文章如下:

  1. 業(yè)界大佬阮一峰老師的ES6標準入門
  2. 一位道友的理解 JavaScript 中的 for…of 循環(huán)
  3. github上的You-Dont-Know-JS
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末嗜闻,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子桅锄,更是在濱河造成了極大的恐慌琉雳,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件友瘤,死亡現(xiàn)場離奇詭異翠肘,居然都是意外死亡,警方通過查閱死者的電腦和手機辫秧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門束倍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人盟戏,你說我怎么就攤上這事绪妹。” “怎么了抓半?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵喂急,是天一觀的道長。 經(jīng)常有香客問我笛求,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任探入,我火速辦了婚禮狡孔,結果婚禮上,老公的妹妹穿的比我還像新娘蜂嗽。我一直安慰自己苗膝,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布植旧。 她就那樣靜靜地躺著辱揭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪病附。 梳的紋絲不亂的頭發(fā)上问窃,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音完沪,去河邊找鬼域庇。 笑死,一個胖子當著我的面吹牛覆积,可吹牛的內容都是我干的听皿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼宽档,長吁一口氣:“原來是場噩夢啊……” “哼尉姨!你這毒婦竟也來了?” 一聲冷哼從身側響起吗冤,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤又厉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后欣孤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體馋没,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年降传,在試婚紗的時候發(fā)現(xiàn)自己被綠了篷朵。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡婆排,死狀恐怖声旺,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情段只,我是刑警寧澤腮猖,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站赞枕,受9級特大地震影響澈缺,放射性物質發(fā)生泄漏坪创。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一姐赡、第九天 我趴在偏房一處隱蔽的房頂上張望莱预。 院中可真熱鬧,春花似錦项滑、人聲如沸依沮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽危喉。三九已至,卻和暖如春州疾,著一層夾襖步出監(jiān)牢的瞬間辜限,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工孝治, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留列粪,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓谈飒,卻偏偏與公主長得像岂座,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子杭措,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容

  • 特別說明费什,為便于查閱,文章轉自https://github.com/getify/You-Dont-Know-JS...
    殺破狼real閱讀 568評論 0 0
  • [TOC] 參考阮一峰的ECMAScript 6 入門參考深入淺出ES6 let和const let和const都...
    郭子web閱讀 1,781評論 0 1
  • 一手素、ES6簡介 ? 歷時將近6年的時間來制定的新 ECMAScript 標準 ECMAScript 6(亦稱 ...
    一歲一枯榮_閱讀 6,078評論 8 25
  • 古人說天下興亡鸳址,匹夫有責。老師說擔當就是什么事都是自己做泉懦。而我覺得擔當就是一種責任感稿黍。 在上二年級...
    梔子花開1234閱讀 215評論 0 0
  • 冬日午后巡球,陽光晦暗。暖氣片里滾動的水聲似我們空耗的年華在悲嚎邓嘹。 弱小如我酣栈,每一天苦心專營周旋于...
    張四少閱讀 146評論 0 0