ES2015(ES6)學(xué)習(xí)手冊(cè)

作用域

  • 全局作用域
  • 函數(shù)作用域
  • 塊級(jí)作用域(es6)

let

  • let 聲明的變量只在所處的塊級(jí)有效
  • let沒有變量聲明提升

需要注意的一點(diǎn):

for (let i = 0;i < 3; i++) {
     let i = "xxx"
     console.log(i);
}

其實(shí)在此處是兩層的塊級(jí)作用域

const

  • const 與 let一樣作用域都是塊級(jí)
  • const只用來聲明常量
  • const聲明的時(shí)候必須復(fù)制邻吭,否則會(huì)報(bào)錯(cuò)
const obj = {}
obj.name = "sam"

這種情況不會(huì)報(bào)錯(cuò),根本原因是obj指向的地址是沒變的

數(shù)組的解構(gòu)

const [first, second, third] = [1,2,3]
const [first, second, third, fourth = 4] = [1,2,3]
const [first, ...rest] = [1,2,3,4]

對(duì)象的解構(gòu)

const obj = {name: "xxx", age: 18}
const {name,age} = obj

模板字符串

const param = "world"
const str = `hello,  //可換行
${param}`   //嵌入變量以及script語句
console.log(str)

還一個(gè)比較特殊的使用方式是帶標(biāo)簽

const  name = "sam"

function tagFn (string, name) {
    console.log(string, name) // 可以在這部分做對(duì)字符串的修飾
    return string[0] + name + string[1]
}

const result = tagFn`hi, ${name}.`
console.log(result)

字符串?dāng)U展方法

includes()
startsWith()
endsWith()

參數(shù)默認(rèn)值

function foo (a = 1) {
    console.log(a )
}
foo()

剩余參數(shù)

function foo (...rest) { //只能用在形參的最后一位 并且只能使用一次
    console.log(rest)
}
foo(1,2,3,4)

展開數(shù)組

const arr = [1,2,3]
console.log.apply(console, arr)//兩種方式等同
console.log(...arr)

箭頭函數(shù)

const inc = (n,m) => {
    return n + m
}
console.log(inc(1,2))

箭頭函數(shù)不會(huì)改變this的指向

對(duì)象字面量的增強(qiáng)

const bar = "2"
const obj = {
    foo: 1,
    bar,
    fn() {
        console.log("fnfnfnfnfnfn")
    }
}
obj[1+1] = 3
obj.fn()

對(duì)象的擴(kuò)展方法

Object.assign()

const obj1 = {
    a:1,
    b:2
}
const obj2 = {
    a:3,
    c:4
}
const obj = Object.assign(obj1, obj2)
console.log(obj)
console.log(obj === obj1)
//{ a: 3, b: 2, c: 4 }
//true

Object.is()

Object.is(+0 === -0)

Proxy

Proxy在目標(biāo)對(duì)象的外層搭建了一層攔截,外界對(duì)目標(biāo)對(duì)象的某些操作必須通過這層攔截

const person = {
    name: "sam",
    age: 18
}
const personProxy = new Proxy(person, {
    get(target, property) {
        
        return property in target ? target[property] : "default"
    },
    set(target, property, value) {
        if (property === "age") {
            if (!Number.isInteger(value)){
                throw new TypeError(`${value} is not an int`)
            }
        }
        target[property] = value
    }
})

personProxy.age = 12
personProxy.sex = "man"

我們發(fā)現(xiàn)proxyObject.defineProperty()的作用相似糙箍,那么兩者有什么區(qū)別呢筏勒?

  • Object.defineProperty()只能監(jiān)控到對(duì)象屬性的讀寫
  • proxy 可監(jiān)控更多操作例如屬性刪除衅金,對(duì)象方法調(diào)用
handle 觸發(fā)條件
get 讀取某個(gè)屬性
set 寫入某個(gè)屬性
has in 操作符
deleteProperty delete 操作符
getProperty Object.getPropertypeOf()
setProperty Object.setPrototypeOf()
isExtensible Object.isExtensible()
preventExtensions Object.preventExtensions()
getOwnPropertyDescriptor Object.getOwnPropertyDescriptor()
defineProperty Object.defineProperty()
ownKeys Object.keys() 耙考、Object.getOwnPropertyNames()耘斩、Object.getOwnPropertySymbols()
apply 調(diào)用一個(gè)函數(shù)
construct 用 new 調(diào)用一個(gè)函數(shù)

對(duì)數(shù)組監(jiān)視
本質(zhì): 重寫數(shù)組的操作方法合陵。
proxy監(jiān)視數(shù)組

const list = []

const listProxy = new Proxy(list, {
    set(target, property, value) {
        console.log("push", property, value)
        target[property] = value
        return true
    }
})
listProxy.push(100)

非侵入便可監(jiān)視

Reflect

Reflect 是一個(gè)靜態(tài)類枢赔,使用方式類似Math
Reflect成員方法就是Proxy處理對(duì)象的默認(rèn)實(shí)現(xiàn)。
Reflect提供了一套用于操作對(duì)象的API拥知,詳情見以上表格

const obj = {
    name: "zicoo",
    age: 18
}
// console.log("name" in obj)
console.log(Reflect.has(obj, "name"))
// console.log(delete obj[age])
console.log(Reflect.deleteProperty(obj, "age"))
// console.log(Object.keys(obj))
console.log(Reflect.ownKeys(obj))

Promise

提供了一種更優(yōu)的異步編程方案
具體可見之前的文章《Promise核心功能從原理到實(shí)現(xiàn)

class 類

class Person {
    constructor (name) {
        this.name = name
    }
    say() {
        console.log(`my name is ${this.name}`)
    }
    static create(name) {
        return new Person(name)
    }
}

const zicoo = new Person("zicoo")
zicoo.say()
const sam = Person.create("sam")
sam.say()

class Student extends Person {
    constructor(name, number) {
        super(name)
        this.number = number
    }
    hello() {
        super.say()
        console.log("student say hello")
    }
}
const tom = new Student("tom", 10)
tom.hello()

Set 數(shù)據(jù)結(jié)構(gòu)

  • 可看做集合
  • Set中數(shù)據(jù)不重復(fù)
const s = new Set();
s.add(1).add(2).add(1)
console.log(s)

//s.forEach()
//for (let i of s)
// s.zie
// s.has(1)
// s.delete(2)
// s.clear()

Set有個(gè)常見的場景是用來數(shù)組去重

const arr = [1,2,3,1,3,2]
const result = Array.from(new Set(arr))
// const result = [...new Set(arr)]
console.log(result)

Map數(shù)據(jù)結(jié)構(gòu)

Object類似都是存的鍵值對(duì)踏拜,但是Object的key只能為String類型

const obj = {}
obj[true] = 123
obj[123] = 123
obj[{a: 1}] = 123
console.log(Reflect.ownKeys(obj))
//[ '123', 'true', '[object Object]' ]
console.log(obj[{}])
// 123

我們發(fā)現(xiàn)真正對(duì)象的key是字符串, 并且我們發(fā)現(xiàn)這么使用存在的其他問題。
那么Map的出現(xiàn)解決了這些問題

const m = new Map()
const tom = {name: "tom"}
m.set(tom, 90)
// m.get()
// m.delete()
// m.clear()
// m.forEach()

Symbol 數(shù)據(jù)類型

獨(dú)一無二的值
最主要的作用是給對(duì)象增加一個(gè)獨(dú)一無二的屬性

// const obj = {
//     [Symbol("name")]: 123
// }
// console.log(obj)
// 場景  私有成員

const name = Symbol()
const person = {
    [name]: 'zicoo',
    say() {
        console.log(this[name])
    }
}
console.log(person.name)
person.say()

以上就是最簡單的使用低剔,那么Symbol的其實(shí)使用場景呢

console.log(Symbol("foo") === Symbol("foo"))
console.log(Symbol.for("foo") === Symbol.for("foo"))
//false
//true
console.log(Symbol.for(true) === Symbol.for("true"))
// false       證明會(huì)將true 轉(zhuǎn)成字符串

//Symbol 本身有好多方法的標(biāo)識(shí)符
// eg: 
//Symbol.hasInstance
//Symbol.iterator

const obj = {}
console.log(obj.toString())
//[object Object]
const objX = {
    [Symbol.toStringTag] : "XObject"
}
console.log(objX.toString())
//[object XObject]

// 通過 for 無法不按理 objx中的 [Symbol.toStringTag]速梗, Object.keys 也不可以

console.log(Object.getOwnPropertySymbols(objX))
// [ Symbol(Symbol.toStringTag) ]

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

可遍歷所有數(shù)據(jù)類型

基本用法

// 遍歷數(shù)組
const arr = [100,200,300,400]
for (const item of arr) { 
    if (item > 100) {
        break
    }
    console.log(item)
}
// 遍歷map
const m = new Map()
m.set("foo", 123)
m.set("bar", 234)
for(const [key,value] of m) {
    console.log(key, value)
}

當(dāng)我們遍歷數(shù)組時(shí)會(huì)出現(xiàn)什么情況

const obj = {name: "sam"}
for (const item of obj) {
    console.log(item)
}
//obj is not iterable

問題來了報(bào)錯(cuò)了肮塞! 其實(shí) 數(shù)據(jù)結(jié)構(gòu)的 Iterable接口是使用 for ... of 的前提

迭代器

image.png

我們發(fā)現(xiàn)無論Array``Set``Map_proto_原型上都有Symbol(Symbol.iterator)這個(gè)方法。
image.png

我們發(fā)現(xiàn)這個(gè)iterator的作用相當(dāng)于一個(gè)指針姻锁,每調(diào)用一次next(),都會(huì)將value指向下一個(gè)值枕赵,并且done來區(qū)分是不是遍歷完成

const set = new Set(["foo","bar","baz"])
const iterator = set[Symbol.iterator]()
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())

//{ value: 'foo', done: false }
//{ value: 'bar', done: false }
//{ value: 'baz', done: false }
//{ value: undefined, done: true }

那我們簡單實(shí)現(xiàn)一下可迭代接口Iterable

// 實(shí)現(xiàn)可迭代接口(Iterable)

const obj = {
    store: ["foo", "bar", "baz"],
    [Symbol.iterator]: function() { // Iterable
        let index = 0
        const self = this
        return {
            next: function() {  // Iterator
                return  {   //IterationResult
                    value: self.store[index], 
                    done: index++ >= self.store.length
                }
            }
        }
    }
}

for (const item of obj) {
    console.log(item)
}

生成器

function * foo() {
    console.log("111")
    yield 100
    console.log("222")
    yield 200
    console.log("333")
    yield 300
}

const result = foo()
console.log(result.next())
console.log(result.next())
console.log(result.next())
console.log(result.next())



// 使用generator 改造 iterator 方法

const obj = {
    store: ["foo", "bar", "baz"],
    [Symbol.iterator]: function * () { // Iterable
        for(const item of obj.store) {
            yield item
        }
    }
}

for (const item of obj) {
    console.log(item)
}

它還有一個(gè)很重要的使用場景就是 異步編程, 可見之前的文章《異步編程(Promise位隶、Generator拷窜、Async與Await)

ES Modules

后續(xù)有詳細(xì)介紹。略

ES2016

  • Array.propotype.includes
  • 指數(shù)運(yùn)算 eg: Math.pow(2, 10) === 2 ** 10

ES2017

  • Object.vaules: 返回所有值的數(shù)組
  • Object.entries: 返回所有鍵值對(duì)數(shù)組
  • Object.getOwnPropertyDescriptors: 獲取所有屬性 eg: get() set()
  • String.prototype.padStart/String.prototype.padEnd: 填充字符串前面或后面
  • Async/Await
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末涧黄,一起剝皮案震驚了整個(gè)濱河市篮昧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弓熏,老刑警劉巖恋谭,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異挽鞠,居然都是意外死亡疚颊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門信认,熙熙樓的掌柜王于貴愁眉苦臉地迎上來材义,“玉大人,你說我怎么就攤上這事嫁赏∑涞啵” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵潦蝇,是天一觀的道長款熬。 經(jīng)常有香客問我,道長攘乒,這世上最難降的妖魔是什么贤牛? 我笑而不...
    開封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮则酝,結(jié)果婚禮上殉簸,老公的妹妹穿的比我還像新娘。我一直安慰自己沽讹,他們只是感情好般卑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著爽雄,像睡著了一般蝠检。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挚瘟,一...
    開封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天叹谁,我揣著相機(jī)與錄音迟杂,去河邊找鬼。 笑死本慕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的侧漓。 我是一名探鬼主播锅尘,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼布蔗!你這毒婦竟也來了藤违?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤纵揍,失蹤者是張志新(化名)和其女友劉穎顿乒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泽谨,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡璧榄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吧雹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骨杂。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖雄卷,靈堂內(nèi)的尸體忽然破棺而出搓蚪,到底是詐尸還是另有隱情,我是刑警寧澤丁鹉,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布妒潭,位于F島的核電站,受9級(jí)特大地震影響揣钦,放射性物質(zhì)發(fā)生泄漏雳灾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一拂盯、第九天 我趴在偏房一處隱蔽的房頂上張望佑女。 院中可真熱鬧,春花似錦谈竿、人聲如沸团驱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嚎花。三九已至,卻和暖如春呀洲,著一層夾襖步出監(jiān)牢的瞬間紊选,已是汗流浹背啼止。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兵罢,地道東北人献烦。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像卖词,于是被迫代替她去往敵國和親巩那。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

推薦閱讀更多精彩內(nèi)容