ES6新特性匯總

ES6改動很大芜果,可以簡單分為四類
1、解決原有語法的缺陷和不足
例如:let融师,const
2右钾、對原有語法進行增強
解構(gòu)、擴展旱爆、模板字符串
3舀射、新增對象、全新的方法怀伦,全新的功能
Object.assign()脆烟、Proxy對象代理、Reflect 等等
4房待、全新的數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)
set邢羔、map、class桑孩、迭代器拜鹤、生成器 等等

一、解決原有語法的缺陷和不足

1流椒、let:塊級作用域署惯,沒有變量提升

用途:for循環(huán)的計數(shù)器(for循環(huán)內(nèi)部let聲明的變量同樣擁有塊級作用域);循環(huán)事件綁定不必采用閉包形式

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

2镣隶、const: 恒量/常量极谊;聲明后不能修改內(nèi)存地址,可修改屬性成員

最佳實踐:不用var安岂,主用const轻猖,配合let

二、對原有語法的增強

1域那、數(shù)組的解構(gòu):根據(jù)數(shù)組對應(yīng)的位置提取對應(yīng)的值賦給對應(yīng)的變量

let arr = [1,2,3]
let [x, y, z] = arr

如果未取到對應(yīng)的值咙边,賦值“undefined”
可以用...運算符

var [x, ...other] = arr

可以設(shè)置默認(rèn)值

var [x='0', y, z] = arr

用途:字符串截取

const str = 'http://www.baidu.com?titile=article'
var [, strParam] = str.split('?')

2猜煮、對象的解構(gòu):根據(jù)屬性名提取

const obj = {name: 'zdd', age: 18}
const { name, age } = obj

如果想換一個變量名&添加默認(rèn)值

const {name: objName='www', age} = obj

應(yīng)用場景:代碼簡化

const { log } = console
log('hh')

3、模板字符串:字符串增強

1败许、可換行
2王带、可使用插值表達式添加變量,變量也可以替換為可執(zhí)行的js語句:

let str = `生成一個隨機數(shù):${ Math.random() }`

標(biāo)簽?zāi)0遄址幸螅瑯?biāo)簽相當(dāng)于一個自定義函數(shù)愕撰,自定義函數(shù)的第一個參數(shù)是被差值表達式截取的數(shù)組

    // 標(biāo)簽?zāi)0遄址?    const name = 'www';
    const isMan = true
    const tagFn = function (strings, name, isMan) {
      let sex = isMan ? 'man' : 'woman';
      return strings[0] + name + strings[1] + sex + strings[2]
    }
    const result = tagFn`hey, ${name} is a ${isMan}.`

4、字符串的擴展方法

1醋寝、includes
2搞挣、startWith
3、endsWith

5音羞、函數(shù)參數(shù)增強:參數(shù)默認(rèn)值

只有當(dāng)參數(shù)為不傳或傳入undefined時使用默認(rèn)值

    const fn = function (x=1, y) {
      console.log(x)
      console.log(y)
    }
    fn()

6囱桨、...操作符:收起剩余數(shù)據(jù)、展開數(shù)組

收取剩余參數(shù):取代arguments嗅绰,arguments是一個類數(shù)組舍肠,...操作符是一個數(shù)組類型,可以使用數(shù)組方法
1窘面、僅使用一次
2貌夕、放在參數(shù)最后

    const fn = function (x, ...y) {
      console.log(y.slice(0))
    }
    fn(1,2,3,4,5)

展開數(shù)組

    const spredArr = [1,2,3,4]
    console.log(...spredArr)
    console.log.apply(this, spredArr) //es5代替方案

7、箭頭函數(shù):簡化寫法

箭頭函數(shù)的this指向上級作用域

    const name = 'tony'
    const person = {
      name: 'tom',
      say: () => console.log(this.name),
      sayHello: function () {
        console.log(this.name)
      },
      sayHi: function () {
        setTimeout(function () {
          console.log(this.name)
        }, 500)
      },
      asyncSay: function () {
        setTimeout(()=>console.log(this.name), 500)
      }
    }
    person.say()  //tony
    person.sayHello() //tom
    person.sayHi() //tony
    person.asyncSay()  //tom

8民镜、對象字面量的增強

1啡专、如果key與value變量名相同,省略:value
2制圈、省略函數(shù):function
3们童、計算屬性:[Math.random()]

   const bar = 'bar'
    const obj = {
      bar,
      fn () {
        console.log('1111')
      },
      [Math.random()]: '123'
    }
    console.log(obj)

三、新增對象鲸鹦、全新的方法慧库、全新的功能

1、Object.assign():合并多個對象馋嗜,第一個參數(shù)就是最終的返回值齐板,如果對象的屬性名相同,后面的覆蓋前面的

用途:復(fù)制對象葛菇,給options屬性賦默認(rèn)值

    let objA = {
      a: 'aa',
      b: 'bb'
    }
    let objB = {
      b: 'dd',
      c: 'ee'
    }
    let result = Object.assign({}, objA, objB)
    result.a = 'cc'
    console.log(objA, result) //{a: "aa", b: "bb"} {a: "cc", b: "dd", c: "ee"}

2甘磨、Object.is():判斷兩個值是否相等,返回布爾值

用途:es5中眯停,對于0的判斷不區(qū)分正負(fù)值济舆,-0 == +0返回true,NaN == NaN返回 返回false莺债;
Object.is()規(guī)避了這些問題

    Object.is(+0, -0)//false
    Object.is(NaN, NaN) //true

3滋觉、Proxy:代理對象

基本用法

    const person = {
      name: 'www',
      age: '20'
    }
    const personProxy = new Proxy(person, {
      get(target, key) {
        return target[key] ? target[key] : 'default'
      },
      set(target, key, value) {
        target[key] = value % 2 ? value : 99
      }
    })
    console.log(person.xxx) // undefined
    console.log(personProxy.xxx) // default
    console.log(personProxy.age) //20
    personProxy.age = 100
    console.log(personProxy) //{name: "www", age: 99}

這里注意的一點是签夭,這里被攔截的是”personProxy“,而不是”person“
與Object.definedProperty()的比較:
1椎侠、相比與Object.definedProperty只能監(jiān)聽get,set行為第租,proxy監(jiān)聽的行為更多一些,has我纪、deleteProperty ... 等很多
2慎宾、對于數(shù)組的push,pop等操作,proxy是監(jiān)聽的整個對象的行為宣羊,所以通過set方法能夠監(jiān)聽到;而definedProperty需要指定該對象的屬性名汰蜘,對于數(shù)組來說仇冯,就是指定數(shù)組的下標(biāo),是監(jiān)聽不到數(shù)組的push,pop等操作的

    let arr = []
    let arrProperty = new Proxy(arr, {
      set (target, key, value) {
        console.log(target, key, value) //[1] "length" 1
        target[key] = value
        return true
      }
    })
    arrProperty.push(1)
    console.log(arrProperty) //[1]

3族操、proxy以非侵入的方式苛坚,監(jiān)聽了對象的讀寫;definedProperty需要指定具體需要監(jiān)聽對象的屬性名色难,與上面的數(shù)組類似泼舱,如果想要監(jiān)聽一個含有多個屬性的對象的讀寫行為,definedProperty需要遍歷這個對象的所有屬性

4枷莉、Reflect: 封裝操作對象的統(tǒng)一API

在之前的es5中娇昙,操作對象有很多種方式

    const obj = {
      name: '111',
      age: '22'
    }
    // 判斷對象某個屬性是否存在
    console.log('name' in obj)
    // 刪除某個屬性
    console.log(delete obj['name'])
    // 獲取對象key
    console.log(Object.keys(obj))

對于不同的操作行為,使用的方式卻不同笤妙,Reflect的目的是使用同一套方式去操作對象

    const obj = {
      name: '111',
      age: '22'
    }
    // 判斷對象某個屬性是否存在
    console.log(Reflect.has(obj,'name'))
    // 刪除某個屬性
    console.log(Reflect.deleteProperty(obj, 'name'))
    // 獲取對象key
    console.log(Reflect.ownKeys(obj))

5冒掌、用于處理異步,解決回調(diào)函數(shù)的地獄式嵌套問題

四蹲盘、全新的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)類型

1股毫、class 類

es5寫法

    function People (name) {
      // 設(shè)置實例屬性
      this.name = name;
    }
    // 設(shè)置實例的共享方法
    People.prototype.sayHi = function () {
      console.log(this.name)
    }
    let p = new People('tom')
    p.sayHi()

使用class更易理解,結(jié)構(gòu)清晰

      class Peopel {
        constructor (name) {
          this.name = name
        }
        say () {
          console.log(this.name)
        }
      }
      const p = new Peopel('tony')
      p.say()

類的繼承

      class Peopel {
        constructor (name) {
          this.name = name
        }
        say () {
          console.log(this.name)   //tom召衔,在子類的sayAge中調(diào)用
        }
      }
      class Worker extends Peopel {
        constructor (name,age) {
          super(name)
          this.age = age
        }
        sayAge () {
          super.say()
          console.log(this)  // Worker {name: "tom", age: 18}
          console.log(this.age) // 18
        }
      }
      const p = new Worker('tom', 18)
      p.sayAge()

類的繼承還是通過原型鏈的方式實現(xiàn)铃诬,具體可以看下babel轉(zhuǎn)換后的代碼
super可以作為函數(shù)調(diào)用,也可以作為對象調(diào)用
作為函數(shù)調(diào)用時苍凛,只能在子類的constructor中調(diào)用趣席,此時執(zhí)行父類的構(gòu)造函數(shù)constructor,執(zhí)行父類構(gòu)造函數(shù)時醇蝴,this指向的是子類Worker吩坝,所以實例p會有name屬性(對于super理解的還是不夠,后面要單獨學(xué)習(xí)下)

2哑蔫、set數(shù)據(jù)結(jié)構(gòu):可以理解為集合钉寝,不重復(fù)

      const s = new Set()
      s.add(1).add(2).add(3)
      console.log(s) //{1, 2, 3}
      console.log(s.size) // 3
      const arr = [1,2,3,2,4]
      console.log([... new Set(arr)]) //[1,2,3,4]

3弧呐、map數(shù)據(jù)結(jié)構(gòu)

es5中的對象key只能是字符串,map的key可以是任意數(shù)據(jù)類型, 可以通過get,set,has等操作map

      const m = new Map()
      const tom = {name: '99'}
      m.set(tom, 90)
      console.log(m.get(tom))
      m.forEach((value, key) => {
        console.log(value, key)
      })

4嵌纲、Symbol新的數(shù)據(jù)結(jié)構(gòu)俘枫,唯一值

用途:防止全局對象中,某個屬性名重名逮走,產(chǎn)生沖突鸠蚪;定義私有屬性,外部訪問不到师溅,且遍歷不到

      const s = Symbol('描述')
      console.log(s)  
      const obj = {
        [Symbol('私有屬性')]: '11'
      }
      console.log(obj)   //obj對象Symbol('私有屬性')這個屬性外部訪問不到
      console.log(Object.keys(obj)) //[]
      console.log(Object.getOwnPropertySymbols(obj)) //[Symbol(私有屬性)]

      const s1 = Symbol.for('111')
      const s2 = Symbol.for('111')
      console.log(s1 === s2) //true

5茅信、for ... of 遍歷

es5中,使用for ... in 遍歷鍵值對結(jié)構(gòu)數(shù)據(jù)墓臭,使用forEach遍歷數(shù)組
es6中新增了set,map數(shù)據(jù)結(jié)構(gòu)蘸鲸,for...of是用來統(tǒng)一遍歷擁有某一種特性的數(shù)據(jù)結(jié)構(gòu)(可迭代)

      const arr = [1,2,3] 
      for (const item of arr) {
        // 遍歷數(shù)組
        console.log(item)
      }
      const s = new Set()
      s.add(1).add(2).add(3)
      for (const item of s) {
        // 遍歷set結(jié)構(gòu)
        console.log(item)
      }
      const m = new Map([
        ['name','昵稱'],
        ['title', '標(biāo)題']
      ])
      for (const [key, value] of m) {
        // 遍歷map結(jié)構(gòu)
        console.log(key)
        console.log(value)
        console.log(m.get(key))
      }

      const newSet = new Set([
        ['name','昵稱'],
        ['title', '標(biāo)題']
      ])
      const newMap = new Map(newSet)
      for (const [key, val] of newMap) {
        // 遍歷set初始化后的map結(jié)構(gòu)
        console.log(key)
        console.log(val)
      }

      const obj = {
        name: 'ttt',
        age: '19'
      }
      for (const [key, val] of obj) {
        // 遍歷對象報錯 Uncaught TypeError: obj is not iterable
        console.log(key, val)
      }

上面代碼中,for...of可以遍歷數(shù)組窿锉,set, map酌摇,但是卻不能遍歷對象,是因為對象沒有可迭代接口

6嗡载、可迭代接口

在瀏覽器中打印一個數(shù)組窑多,在數(shù)組的原型對象上有一個Symbol內(nèi)置屬性Symbol.iterator方法,該方法會返回一個iterator對象洼滚,該對象包含一個next()方法埂息,調(diào)用iterator.next()會返回一個迭代器結(jié)果對象iterationResult,iterationResult對象包含兩個值遥巴,value為遍歷的item耿芹,done為當(dāng)前數(shù)據(jù)是否遍歷完成

      const iterator = arr[Symbol.iterator]()
      console.log(iterator) // Array Iterator {}
      const ite = iterator.next()
      console.log(ite) //{value: 1, done: false} value為迭代器的值,done標(biāo)識是否遍歷完

由于上面代碼中obj對象不沒有Symbol.iterator的內(nèi)置方法挪哄,所以它不是一個可迭代對象吧秕,當(dāng)使用for...of遍歷時就報錯了,下面手動實現(xiàn)obj可迭代

      let iteratorObj = {
        //iteratorObj是可迭代對象 iterable
        name: 'ttww',
        age: '18',
        [Symbol.iterator] () {
          let index = 0;
          let arr = []
          for (const key in iteratorObj) {
            arr.push([key, iteratorObj[key]])
          }
          return {
          //返回的對象叫iterator
            next () {
              return {
                //結(jié)果對象iterationResult
                value: arr[index],
                done: index++ >= arr.length
              }
            },
          }
        }
      }
      for (const [key, val] of iteratorObj) {
        console.log(key, val)
      }

上面代碼中迹炼,iteratorObj有了可迭代接口砸彬,認(rèn)為是可迭代對象iterable;Symbol.iterator方法返回的對象是迭代器對象iterator斯入;迭代器對象next方法返回的對象是迭代器結(jié)果對象iterationResult

6砂碉、生成器 generator

用途:處理異步調(diào)用回調(diào)嵌套的問題

      function *geFn () {
        console.log('111')
        yield 100
        console.log('222')
        yield 200
        console.log('333')
        yield 300
      }
      let generator = geFn()
     
      console.log(generator.next())  //111 {value: 100, done: false}
      console.log(generator.next())  //222 {value: 200, done: false}
      console.log(generator.next())  //333 {value: 300, done: false}

在函數(shù)名前面加一個"*",函數(shù)就變?yōu)樯善骱瘮?shù)刻两,執(zhí)行該函數(shù)時增蹭,里面的函數(shù)不會立即執(zhí)行,而是會返回一個生成器對象磅摹,調(diào)用生成器對象的.next方法函數(shù)開始執(zhí)行滋迈,當(dāng)遇到”yield“關(guān)鍵字霎奢,函數(shù)會停止執(zhí)行,并把yield的值當(dāng)做next方法返回對象的value; 當(dāng)下次調(diào)用next方法時饼灿,函數(shù)從當(dāng)前位置開始繼續(xù)執(zhí)行
生成器函數(shù)執(zhí)行后返回的生成器對象generator幕侠,內(nèi)部也是實現(xiàn)了迭代器接口,所以可以使用for...of來遍歷

      function *geFn () {
        console.log('111')
        yield 100
        console.log('222')
        yield 200
        console.log('333')
        yield 300
      }
      let generator = geFn()
    
      for (const item of generator) {
        console.log(item)
      }

可以使用生成器函數(shù)改寫上面對象的迭代器方法

      let iteratorObj = {
        name: 'ttww',
        age: '18',
        [Symbol.iterator]:function *() {
          let index = 0;
          let arr = []
          for (const key in iteratorObj) {
            arr.push([key, iteratorObj[key]])
          }
          // for (let i =0; i<arr.length; i++) {
          //   console.log(arr[i])
          //   yield arr[i]
          // }
         
          for (const item of arr) {
            yield item
          }
          // arr = ['b',3,4,5]
          // return {
          //   next () {
          //     return {
          //       value: arr[index],
          //       done: index++ >= arr.length
          //     }
          //   },
          // }
        }
      }
      for (const [key, val] of iteratorObj) {
        console.log(key, val)
      }

這里有一個注意的點就是在循環(huán)arr數(shù)組時碍彭,不能是有forEach遍歷晤硕,是因為forEach里需要傳一個回調(diào)函數(shù),這個函數(shù)不是生成器函數(shù)庇忌,在非生成器函數(shù)里使用yield關(guān)鍵字會報錯

ES2016

1舞箍、數(shù)組新增方法:includes

      const arr = [1,2,3]
      console.log(arr.includes(2))  //true

2、指數(shù)運算符

console.log(2 ** 10) //1024

ES2017

1皆疹、Object.values()疏橄,以數(shù)組的形式,返回對象所有的值

      let obj = {
        title: 'wwwww',
        age: 199
      }
      console.log(Object.values(obj)) //["wwwww", 199]

2墙基、Object.entries()软族,以數(shù)組的形式刷喜,返回對象的所有鍵值對

let obj = {
        title: 'wwwww',
        age: 199
      }
console.log(Object.entries(obj)) //[["title", "wwwww"],["age", 199]]

可以將對象轉(zhuǎn)為map數(shù)據(jù)結(jié)構(gòu)

      let obj = {
        title: 'wwwww',
        age: 199
      }
     
      let m = new Map(Object.entries(obj))
      console.log(m) //{"title" => "wwwww", "age" => 199}

3残制、Object.getOwnPropertyDescriptor()
獲取一個對象的完整描述信息,可用于將一個對象的get掖疮,set屬性賦值給另一個對象

      let obj = {
        firstName: 'abc',
        lastName: '123',
        get fullName () {
          return this.firstName + this.lastName
        }
      }
      console.log(obj.fullName) //abc123
      const p2 = Object.assign({}, obj)
      // 此時賦值給p2的僅僅是fullName屬性的值初茶,并沒有fullName屬性的getter
      p2.firstName = '456'
      console.log(p2.fullName)  //abc123

      const description = Object.getOwnPropertyDescriptors(obj)
      console.log(description)
      const p3 = Object.defineProperties({}, description);
      p3.firstName = '789'
      console.log(p3.fullName)  //789123

4、字符串的padEnd()浊闪、padStart()方法
5恼布、async/await

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搁宾,隨后出現(xiàn)的幾起案子折汞,更是在濱河造成了極大的恐慌,老刑警劉巖盖腿,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爽待,死亡現(xiàn)場離奇詭異,居然都是意外死亡翩腐,警方通過查閱死者的電腦和手機鸟款,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茂卦,“玉大人何什,你說我怎么就攤上這事〉攘” “怎么了处渣?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵伶贰,是天一觀的道長。 經(jīng)常有香客問我霍比,道長幕袱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任悠瞬,我火速辦了婚禮们豌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘浅妆。我一直安慰自己望迎,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布凌外。 她就那樣靜靜地躺著辩尊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪康辑。 梳的紋絲不亂的頭發(fā)上摄欲,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天,我揣著相機與錄音疮薇,去河邊找鬼胸墙。 笑死,一個胖子當(dāng)著我的面吹牛按咒,可吹牛的內(nèi)容都是我干的迟隅。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼励七,長吁一口氣:“原來是場噩夢啊……” “哼智袭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起掠抬,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤吼野,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后两波,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞳步,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年雨女,在試婚紗的時候發(fā)現(xiàn)自己被綠了谚攒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡氛堕,死狀恐怖馏臭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤括儒,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布绕沈,位于F島的核電站,受9級特大地震影響帮寻,放射性物質(zhì)發(fā)生泄漏乍狐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一固逗、第九天 我趴在偏房一處隱蔽的房頂上張望浅蚪。 院中可真熱鬧,春花似錦烫罩、人聲如沸惜傲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盗誊。三九已至,卻和暖如春隘弊,著一層夾襖步出監(jiān)牢的瞬間哈踱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工梨熙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留开镣,地道東北人。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓串结,卻偏偏與公主長得像哑子,于是被迫代替她去往敵國和親舅列。 傳聞我的和親對象是個殘疾皇子肌割,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361