ES2015到ES2017(即ES6开始)新特性总结

ES2015 俗称ES6 新特性

官网链接
https://www.ecma-international.org/ecma-262/6.0/

新特性主要目的:

  • 解决原有语法上的一些问题或者不足
    let、const

  • 对原有语法增强
    结构、展开、模板字符串等

  • 全新的对象、方法、功能
    Promise、Proxy、Reflect等

  • 全新的数据类型、数据结构
    set 、Map等

  • 作用域
    全局作用域(旧版本)
    函数作用域(旧版本)
    块级作用域

  • 声明变量
    var (旧版本,可实现变量声明的提升,不规范)

    let
    let声明的成员,删除变量声明的提升功能,只能在其块级作用域中被访问到

    const
    const声明的成员是只读的,只能修改const声明变量的内容,不能改变变量内存地址。
    全局 const声明的变量不会挂载到windows上。因为没有块级作用域环境。

const arr = [1,2,3]
arr.push(4)
// [1,2,3,4]
arr = [1,2]
// 报错
  • 剩余参数( ... 的 rest 作用)
  function (param1,param2,...params) {

  ​ statements

  }
  • 数组解构( ... 的 解构 作用)

    [...arr]

​ ...必须在最后一个元素前使用(越界会被解构成undefind)

​ [name='xiaoming',age] = arr 解构可赋值默认值

  • 模板字符串
    字符串换行直接换行实现
    插值表达式

    `${js语句 1+2 或 变量 name}
       这一句是换行后的内容。`
    

    可以添加标签tag(实际是个函数)

  • includes()、startWith()、endsWith() 字符串扩展方法

  • 参数默认值()

    在需要默认值的形参后加默认值

    function (name = xiaoming) {}

  • 参数扩展,数组扩展

    参数扩展 function (...args) {}

    数组扩展 const arr = ['foo', 'bar', 'baz']

    console.log.apply(console, arr) =>旧

    console.log(...arr) =>新

  • 箭头函数

    fira Code 编程连体字体

    不会改变this指向。没有自己的thisargumentssupernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

    不会绑定普通函数的arguments对象

普通函数中,this始终会指向调用者对象

可简化返回值的表达方式

  • 对象字面量

    value为值:当属性名和属性值名称相同时,可省略value

    value为普通函数():可省略:与 function关键字

    可以使用表达式或函数返回值作为属性名

  const obj = {
  ​ name,
  ​ method () {
  ​     return "hello world"
  ​ },
  ​ [1+1] : "this is JS"
  }
  • 对象扩展

    相同属性覆盖,不同属性扩展

    Object.assign

    const source1 = {
      a: 123,
      b: 123
    }
    
    const source2 = {
      a: 123,
      b: 123
    }
    
    const target = {
      b: 456,
      c: 456
    }
    const newTarget = Object.assign(target, source1, source2)
    console.log(newTarget === target)
    // {a:123, c: 456, b: 123}
    // true
    
    // 应用🌰:
    function (obj) {
      // 复制,标识默认值
      const newObj = Object.assign({},obj)
      newObj.name = obj.name || "defaultValue"
    }
    
    
  • Object.is

    比较的三种形式:

    方式 特点
    == 比较前会进行类型转换(0==faluse 成立)
    === 推荐常用:严格模式(0===faluse 不成立,+0===-0 不成立,NaN === NaN 不成立)
    Object.is() +0===-0 成立,NaN === NaN 成立
  • Object.defineProperty 的加强版---> Proxy

    为对象设置访问代理器,监听对象的读写等

    二者比较:

    类型 功能 具体表现
    Proxy 监听范围 1. 可监视到属性的读写、调用,删除等操作
    2. 可监听和重写数组方法(set 监听数组的写入 ,获取 下标 值)
    Object.defineProperty 监听范围 只能监听属性的读写
    Proxy 监听形式 必须特定写法才能监听特定属性
    Object.defineProperty 监听形式 Proxy是以非侵入方式监听,不必指定属性名
 ```js
 Object.defineProperty(person,"name",{
   set() {}
   get() {}
 })
 ```
  • Reflect

    静态方法,不能实例化,有13个成员方法(14个废弃掉一个),是Proxy处理对象的默认实现,提供了一套统一操作对象的API

    const person = {
      name: "xiaoming",
      sex: "man",
      age: 18
    }
    const personProxy = new Proxy(person, {
      get(target, property) {
          // 监听的对象target,对象的属性property
          return Reflect.get(target,property)
      },
      set(target, property, value) {
          // 监听的对象target,对象的属性property,属性的值value
      },
      deleteProperty (target, property) {
          delete target[property]
      }
    })
    
    delete personProxy.age
    
    
    Reflect.has(person, 'name')
    Reflect.deleteProperty(person, 'age')
    Reflect.ownKeys(person)
    
    
  • Promise

    用于解决异步编程的新增解决方案

  • class 类,继承

    class Person {
    
      contructor (name) {
    
          this.name = name
      }
      // 静态方法
      static create (name) {
        return new Person(name)
      }
      // 实例方法
      say () {
    
      }
    }
    
    class Student extends Person {
      contructor (name) {
        super(name)
      }
      say(){
        super.say()
      }
    }
    
    const p1 = new Person('xiaoming')
    const p1 = Person.create('xiaoming')
    const s = new Person('xiaohong')
    
  • set

    常用作数组去重

    常见方法:clear()、add(value)

  • map

    与对象的本质都是键值对集合。但是 对象的key必须为字符串或者Symbol,map的key可以使用任意数据类型

    // Obj
    const obj = {
      name: "xiaoming"
    }
    Object.keys(obj)
    // ['name']
    
    // Map
    const map = new Map()
    const name = {leader: 'xiaoming',member: 'xiaohong'}
    map.set(name,'xiaomingTeam')
    map.get(name)
    map.forEach(value,key) => {
      console.log(value,key)
    }
    // 'xiaomingTeam' {leader: 'xiaoming',member: 'xiaohong'}
    
  • Symbol

    用于表示对象的一个独一无二的属性名(例如避免对象属性扩展时覆盖)

    const name = Symbol()
    const person = {
      [name]: 'xiaoming',
      say(){
        console.log(`hello ${this[name]}`)
      }
    }
    
    
    

    获取Symbol:

    Object.getOwnPropertySymbols(obj) 只能获取到Symbol属性名。

    以下操作无法获取到Symbol:

    • for in
    • Object.keys(obj)
    • JSON.stringify(obj)

    只能获取到字符串属性名。

    // .for 接收字符串。不是字符串也会转换成字符串
    const s1 = Symbol.for('haha')
    const s2 = Symbol.for('haha')
    console.log(s1 === s2)
    // true
    Symbol.for('true') === Symbol.for(true)
    // true
    
    
    // 标识tag
    const obj = {
      [Symbol.toString]: 'NewObj'
    }
    console.log(obj.toString())
    // [object NewObj]
    
  • for of 循环

    用于遍历数组、伪数组、set、map

    获取到的是数组中每一个元素(map获取到的是[key, value]数组),可以使用break终止循环,而forEach是不能break终止遍历的。

    arr.some()

    arr.every()

    也是可以通过返回true或者false终止遍历的

ES2015提供了Iterable接口,能够使用for of遍历的数据结构。

数组、Map、set都实现了Iterable接口,挂载了iterator方法。iterator.next()可按顺序返回数据结构中的每一个元素,并通过done是否为true来标记循环的结束。

如何使对象 实现for of?

// 实现可迭代接口irerable
const obj = {
  let index = 0
  const originArr = ['hello', 'world','!']
  [Symbol,iterator]: function() {
      // 实现iterator
    return {
      next: function() {
        // 实现  iterationresult
        const result = {
          value: originArr[index],
          done: index++ >= self.originArr.length
        }
        return result
      }
    }
  }
}

迭代器模式:实现统一迭代接口,不用关心数据内部数据结构

  • Generator

    减少异步回调嵌套,提供更好的异步编程解决方案

    // 实现了迭代接口协议
    function * func() {
      return 100  
    }
    const result = func()
    console.log(result)
    // Object [Generator] {}
    console.log(result.next())
    // {value: 100, done: true}
    
    
    // yield 惰性执行迭代
    function * func2() {
      console.log("111")
      yield 100
      console.log("222")
      yield 200
      console.log("333")
      yield 300
    }
    
    const generator = func2()
    console.log(generator.next())
    // 111
    // {value: 100, done: false}
    console.log(generator.next())
    // 111
    // {value: 100, done: false}
    // 222
    // {value: 200, done: false}
    console.log(generator.next())
    // 111
    // {value: 100, done: false}
    // 222
    // {value: 200, done: false}
    // 333
    // {value: 300, done: false}
    
    function * createIdMaker () {
      let id = 1
      while (true) {
         yield id ++
      }
    }
    const idMaker = createIdMaker().next().value
    
    
// 实现可迭代接口irerable
const obj = {
  let index = 0
  const originArr1 = ['hello', 'world','!']
  const originArr2 = ['a','b','c']
  [Symbol,iterator]: function * () {
    const all = [...originArr1, ...originArr2]
      // 实现iterator
      next: function * () {
        // 实现  iterationresult
        for (const item of all) {
          yield item
      }
    }
  }
}
for (const item of obj) {
  console.log(item)
}
  • ES Modules 模块化

ES2016(ECMAScript第七个版本)

  • 数组的includes()

    返回bool值,表达是否存在,也可检测NaN(indexof不能判断NaN(NaN是一个值))

  • 指数运算符

    2 ** 10
    // 1024
    

ES2017 (ECMAScript第八个版本)

  • Object.values

    所有值组成的数组

  • Object.entries

    数组形式返回键值对 ['key', 'value']

  • Object.getOwnPropertyDescriptors

    获取对象的属性完整信息

    const p1 = {
      firstName : 'ming',
      lastName : 'xiao'
      get fullName () {
        return this.firstName + ' ' + this.lastName
      }
    }
    
    const descriptors = Object.getOwnPropertyDescriptors(p1)
    const p2 = Object.defineProperties({},descriptors)
    p2.firstName = 'hong'
    console.log(p2.fullName)
    // hong xiao
    
  • string.prototype.padStart / String.prototype.padEnd

    字符串添加方法

  • 在函数参数中添加尾逗号

    const arr = [100, 200, 300,]

  • async 函数

    配合await,可以彻底解决异步回调嵌套问题,本质上是Promise语法糖

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342