ES6常用新语法总结

319 阅读14分钟

ES6 介绍

ES6的名称为ESMAScript2015(es2015),是2015年6月份发行的,它是最新ECMAScript的代表版本,一是因为相对与es5变化比较大,二是因为它的发行让标准命名规则发生了变化,ES6更准确的缩写名称应该叫ES2015,

ES6的出现最主要的解决了以下几个问题:

  1. 解决原有语法上的一些问题或不足(比如let,const)
  2. 对原有语法进行增强,更加易用(比如解构,展开,参数默认值,模板字符串)
  3. 全新的对象,全新的方法,全新的功能(promise)
  4. 全新的数据类型和数据结构(symbol,Set,Map)

let,const与var的区别

1.var 存在变量提升,let 不存在

//let
console.log(c) //Uncaught ReferenceError: Cannot access 'c' before initialization
let c = 100      

//var
console.log(c) //underfined
var c =100

因为 let 不存在变量提升,所以上面 let 定义的变量会报错,报错的意思是我们想要打印 c 的值,必须先要初始化,然后再去使用它,必须遵循 先声明,后使用 的使用规则。 var 定义的变量结果为 underfined 代码相当于:

var c;//变量提升,但是值不能提升,所以是underfined
console.log(c) //underfined
c = 100

2.let在同一个作用域下不可以重复定义同一个变量值,而var可以

//let
let c = 100 
let c = 200  //报错 Uncaught SyntaxError: Unexpected identifier

//var
var c = 100
var c = 200 
console.log(c) //200 正常运行,会覆盖前一个值

3.有严格的作用域,var属于函数作用域,let属于块级作用域

ES5 中作用域有:全局作用域、函数作用域,没有块作用域的概念。 ES6 中新增了块级作用域,块作用域由**{ }**包括,if 语句和 for 语句里面的 { } 也属于块作用域。

//let
function fun(){
  let n = 10
  if(true){
    let n = 20 //与上面的 n 不属于同一个作用域,所以不受影响
  }
  console.log(n) //10
}
fun()

//var
function fun(){
  var n = 10
  if(true){
    var n = 20 //会覆盖上面的 n 的值
  }
  console.log(n)//20
}
fun()

4. const

4.1 const 声明的变量为只读的,一旦声明,常量的值就不能改变
const a =2; 
a=3;//错误  Uncaught TypeError: Assignment to constant variable.
4.2 const 声明的变量一定要初始化,不能只声明不赋值,
const a; // 错误  Uncaught SyntaxError: Missing initializer in const declaration
 //(const声明中缺少初始化程序)
4.3 const 声明的变量只在块级作用域内有效。
{
  const  a = 3
}
console.log(a) // Uncaught ReferenceError: a is not defined

但是用 const 声明的对象的属性是可以更改的,const 实质上保证的并不是变量的值不得改动,而是变量指向的 内存地址 的值不得改动,对于简单类型数据,值就保存在变量指向的内存地址中,相当于常量。而对于复合型的数据,变量指向的是内存地址保存的是一个指针。const 只能保证指针是不可以被更改,但指针指向的数据结构是可以被改变的。

//以下代码正常执行
const  obj = {}
obj.name="xiaoke" 
console.log(obj) // {name: "xiaoke"}

const  arr = []
arr.push("xiaoke")
console.log(arr) // ["xiaoke"]

数组的解构

  1. 比如我们要取出arr中的值,我们可以使用下面的方式取出,a1,a2,a3代表了相应位置坐标的值
const arr = ['a','b','c']

const [a1,a2,a3] = arr
console.log(a1,a2,a3)//a b c
  1. 如果我们只想取索引为2的值,我们可以:
const arr = ['a', 'b', 'c']

const [, , a3] = arr //用逗号进行占位
console.log(a3)//c
  1. 如果我们想把b和c一起取出来我们可以:
const arr = ['a', 'b', 'c']

const [, ...arr2] = arr
console.log(arr2) //['b','c']
  1. 如果我们想取出一个数组中不确定存在的元素时,我们可以先给这个值赋值默认值,默认值的意思是数组中不存在此元素时,会输出默认值,存在这个值是输出存在的值:
存在
const arr = ['a', 'b', 'c', 'd']
const [a1, a2, a3, a4 = 'dd'] = arr
console.log(a1, a2, a3, a4)
console.log(arr)//a b c d

不存在
const arr = ['a', 'b', 'c']
const [a1, a2, a3, a4 = 'dd'] = arr
console.log(a1, a2, a3, a4)
console.log(arr)// a b c dd

对象的解构

  1. 对象的解构和数组的解构很相似,只是对象的解构不是按索引位置进行取值的,而是取出对象中的key值
const obj = { name: "xuke", age: 22 }

const { age } = obj
console.log(age) //22
  1. 对象和数组一样也可以设置默认值,如果我们想取出一个对象中不确定存在的元素时,我们可以先给这个值赋值默认值,默认值的意思是数组中不存在此元素时,会输出默认值,存在这个值是输出存在的值。
const obj = { name: "xuke", age: 22 }

const { hobby = "eat" } = obj
console.log(hobby) // eat

3.如果我们代码中已经定义了一个与obj中相同的属性名,我们可以使用下面的方式给属性名一个别名,然后再取出

const obj = { name: "xuke", age: 22 }
const name = 'keke'
const { name } = obj
console.log(newname) //会报错:SyntaxError: Identifier 'name' has already been declared

改正
const obj = { name: "xuke", age: 22 }
const name = 'keke'
const { name : newname } = obj
console.log(newname) //xuke

模板字符串

  1. 我们用反引号来包裹起来字符串: ``
const name = 'xuke'
const str = `my name is ${name}`
console.log(str) // my name is xuke
  1. 模板字符串支持换行

const name = 'xuke'
const str = `my name
 is ${name}`
console.log(str)
//my name
//is xuke
  1. ${}中可以使用函数表达式,返回最终值
const str = `my age is ${true ? 22 : 10}`
console.log(str) //my age is 22

字符串的扩展方法

  1. startsWith() 判断是否以某个字符开头
  2. endsWith()判断是否以某个字符结尾
  3. includes()判断是否包含某个字符
const message = 'welcome to beijing.'

console.log(message.startsWith('welcome'))//true
console.log(message.startsWith('wel'))//true
console.log(message.endsWith('beijing'))//false
console.log(message.endsWith('.'))//true
console.log(message.includes('bei'))//true

参数默认值

  1. 当我们给函数传参的时候,我们可以使用以下方法设置默认值
function num(x = 20) {
    return x += x
}
//x不传为undefined时 ,会使用我们的默认值 20
console.log(num()) //40
//传值的时候会使用我们传的值
console.log(num(10)) //20

注意:我们对参数设置默认值的时候,要把带有默认值的参数放到最后面

//错误的写法
function num(a = 20, x) {
    return a + x
}

//正确的写法
function num(a , x = 20) {
    return a + x
}

展开运算符(...)

  1. 合并数组
let a = [1,2,3];
let b = [4,5,6];
let c = [...a,...b]; // [1,2,3,4,5,6]
  1. 替代apply
function f(a,b,c){
  console.log(a,b,c)
}
let args = [1,2,3];
// 以下三种方法结果相同
f.apply(null,args)
f(...args)
f(1,2,3)
//===========
function f2(...args){
  console.log(args)
}
f2(1,2,3) // [1,2,3]

function f3(){
  console.log(Array.from(arguments))
}
f3(1,2,3) // [1,2,3]
  1. 浅拷贝
//数组
var a = [1,2,4]
var b = [...a]
a.push(6)
console.log(b) // [1,2,4]

//对象
var a = {a:1}
var b = {...a}
a.a = 5
console.log(b.a) // 1

箭头函数

使用

const fun = function () {
    return 'hello'
}
const fun2 = () => 'hello'
console.log(fun()) // hello
console.log(fun2())// hello

//===

const nums = [1, 2.3, 2, 46, 6, 4, 3, 2]
const result = nums.filter(num => num % 2 === 0)
console.log(result)//[ 2, 46, 6, 4, 2]

箭头函数不会改变this的指向

const Person = {
    name:'xuke',
    say1:function(){
        console.log(this.name) //xuke 指向Person
    },
    say2:()=>{
        console.log(this.name) //undefined 指向window
    }
}
Person.say1()
Person.say2()

setTimeOut情况:

const Person = {
    name: 'xuke',
    say1: function () {
        setTimeout(function () {//setTimeOut函数体里面的函数题被放到全局作用域去调用
            console.log(this.name) //undefined 
        }, 1000)
        setTimeout(() => {//setTimeOut函数体里面的箭头函数始终指向当前作用域中的this
            console.log(this.name) //xuke
        }, 1000)
    }
}
Person.say1()

对象字面量

  1. 当我们对象中的属性名相等的时候,我们可以把省略:
const name = 'xuke'
//普通用法
const obj1 = {
    name:name,
    age:12
}
//字面量用法
const obj2 = {
    name,
    age:12
}
console.log(obj1) //{ name: 'xuke', age: 12 }
console.log(obj2) //{ name: 'xuke', age: 12 }
  1. 当我们想用表达式生成对象的属性名的时猴,我们可以在[]中写入我们的表达式
//es2015之前
const name = 'xuke'
const obj = {
    name,
    age:12
}
const obj2 = {}
obj2[obj.name] = 'keke'
console.log(obj2) //{ xuke: 'keke' }

//es2015
const name = 'xuke'
const obj = {
    name,
    age:12
}
const obj2 = {
    [obj.name]:'keke'
}
console.log(obj2) //{ xuke: 'keke' }

Object.assign()

Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target),如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性覆盖前面的属性

const source = {
    a:123,
    b:123
}
const target ={
    a:456,
    c:111
}

console.log(Object.assign(target,source)) //{a:123,c:111,b:123}

还可用于对象的浅拷贝,

const source = {
    a:123,
    b:123,
    name:{
        cc:'ccc'
    }
}
const target = Object.assign({},source)
target.a = 333
console.log(target) //{ a: 333, b: 123 }
console.log(source) //{ a: 123, b: 123 }

Proxy

proxy真的用处很大,可是我项目中很少用到,总结一下。

proxy在目标对象的外层搭建了一层拦截,外界对目标对象的某些操作,必须通过这层拦截.

1. 语法

var proxy = new Proxy(target, handler);

new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为

2. 基本用法

var target = {
   name: 'poetries'
 };
 var logHandler = {
   get: function(target, key) {
     console.log(`${key} 被读取`);
     return target[key];
   },
   set: function(target, key, value) {
     console.log(`${key} 被设置为 ${value}`);
     target[key] = value;
   }
 }
 var targetWithLog = new Proxy(target, logHandler);
 
 targetWithLog.name; // 控制台输出:name 被读取
 targetWithLog.name = 'others'; // 控制台输出:name 被设置为 others
 
 console.log(target.name); // 控制台输出: others

targetWithLog 读取属性的值时,实际上执行的是 logHandler.get :在控制台输出信息,并且读取被代理对象 target 的属性。 在 targetWithLog 设置属性值时,实际上执行的是 logHandler.set :在控制台输出信息,并且设置被代理对象 target 的属性的值

3. 保持只返回一个值

// 由于拦截函数总是返回35,所以访问任何属性都得到35
var proxy = new Proxy({}, {
  get: function(target, property) {
    return 35;
  }
});

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

4. Proxy 实例也可以作为其他对象的原型对象

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

let obj = Object.create(proxy);
obj.time // 35

proxy对象是obj对象的原型,obj对象本身并没有time属性,所以根据原型链,会在proxy对象上读取该属性,导致被拦截

5. Proxy的作用

  1. 拦截和监视外部对对象的访问
  2. 降低函数或类的复杂度
  3. 在复杂操作前对操作进行校验或对所需资源进行管理

6.Proxy使用场景

  1. 实现私有变量
var target = {
   name: 'poetries',
   _age: 22
}

var logHandler = {
  get: function(target,key){
    if(key.startsWith('_')){
      console.log('私有变量age不能被访问')
      return false
    }
    return target[key];
  },
  set: function(target, key, value) {
     if(key.startsWith('_')){
      console.log('私有变量age不能被修改')
      return false
    }
     target[key] = value;
   }
} 
var targetWithLog = new Proxy(target, logHandler);
 
// 私有变量age不能被访问
targetWithLog.name; 
 
// 私有变量age不能被修改
targetWithLog.name = 'others'; 

例1:在下面的代码中,我们声明了一个私有的 apiKey,便于 api 这个对象内部的方法调用,但不希望从外部也能够访问 api._apiKey

var api = {  
    _apiKey: '123abc456def',
    /* mock methods that use this._apiKey */
    getUsers: function(){}, 
    getUser: function(userId){}, 
    setUser: function(userId, config){}
};

// logs '123abc456def';
console.log("An apiKey we want to keep private", api._apiKey);

// get and mutate _apiKeys as desired
var apiKey = api._apiKey;  
api._apiKey = '987654321';

很显然,约定俗成是没有束缚力的。使用 ES6 Proxy 我们就可以实现真实的私有变量了,下面针对不同的读取方式演示两个不同的私有化方法。第一种方法是使用 set / get 拦截读写请求并返回 undefined:

let api = {  
    _apiKey: '123abc456def',
    getUsers: function(){ }, 
    getUser: function(userId){ }, 
    setUser: function(userId, config){ }
};

const RESTRICTED = ['_apiKey'];
api = new Proxy(api, {  
    get(target, key, proxy) {
        if(RESTRICTED.indexOf(key) > -1) {
            throw Error(`${key} is restricted. Please see api documentation for further info.`);
        }
        return Reflect.get(target, key, proxy);
    },
    set(target, key, value, proxy) {
        if(RESTRICTED.indexOf(key) > -1) {
            throw Error(`${key} is restricted. Please see api documentation for further info.`);
        }
        return Reflect.get(target, key, value, proxy);
    }
});

// 以下操作都会抛出错误
console.log(api._apiKey);
api._apiKey = '987654321';  

例2:让我们从一个简单的类型校验开始做起,这个示例演示了如何使用 Proxy 保障数据类型的准确性

let numericDataStore = {  
    count: 0,
    amount: 1234,
    total: 14
};

numericDataStore = new Proxy(numericDataStore, {  
    set(target, key, value, proxy) {
        if (typeof value !== 'number') {
            throw Error("Properties in numericDataStore can only be numbers");
        }
        return Reflect.set(target, key, value, proxy);
    }
});

// 抛出错误,因为 "foo" 不是数值
numericDataStore.count = "foo";

// 赋值成功
numericDataStore.count = 333;

例3:对于那些调用频繁、运行缓慢或占用执行环境资源较多的属性或接口,开发者会希望记录它们的使用情况或性能表现,这个时候就可以使用 Proxy 充当中间件的角色,轻而易举实现日志功能

let api = {  
    _apiKey: '123abc456def',
    getUsers: function() { /* ... */ },
    getUser: function(userId) { /* ... */ },
    setUser: function(userId, config) { /* ... */ }
};

function logMethodAsync(timestamp, method) {  
    setTimeout(function() {
        console.log(`${timestamp} - Logging ${method} request asynchronously.`);
    }, 0)
}

api = new Proxy(api, {  
    get: function(target, key, proxy) {
        var value = target[key];
        return function(...arguments) {
            logMethodAsync(new Date(), key);
            return Reflect.apply(value, target, arguments);
        };
    }
});

api.getUsers();

Reflect用法

概述

Reflect是为操作对象而提供的新API,那么我们为什么要去使用它呢?将Object对象的属于语言内部的方法放到Reflect对象上,即从Reflect对象上拿Object对象内部方法,比较方便,可读性更强。

1. Reflect.has(obj,name) 判断对象中的属性是否存在

const object = {
    name:'xuke',
    age:22
}
console.log(Reflect.has(object,'name'))//true

2. Reflect.set(target,propName,propValue)

const object = {
    name:'xuke',
    age:22
}

console.log(Reflect.set(object,'ww','dd'))//true object中不存在会直接添加
console.log(Reflect.set(object,'name','dd'))//true object中存在会覆盖
console.log(object) //{ name: 'dd', age: 22, ww: 'dd' }

3. Reflect.set(target,propName)

const object = {
    name:'xuke',
    age:22
}

console.log(Reflect.get(object,'name'))//xuke  属性名存在直接返回
console.log(Reflect.get(object,'ww'))//undefined  属性名不存在返回undefined

4. Reflect.deleteProperty(obj, name) 删除属性

const object = {
    name:'xuke',
    age:22
}

Reflect.deleteProperty(object,'name')
console.log(object) //{age:22}

5.Reflect.ownKeys (target) 用于返回对象的所有属性

const object = {
    name:'xuke',
    age:22
}

console.log(Reflect.ownKeys(object)) //[ 'name', 'age' ]

6. 上面列举了比较常用的方法,当proxy和Reflect配合起来一起使用:

const object = {
    name:'xuke',
    age:22
}
const proxy = new Proxy(object,{
    get:(target,property)=>{
       return Reflect.get(target,property) //获取被访问的属性
    },
    set:(target,property,value)=>{
        Reflect.set(target,property,value) //设置被访问的属性与新值
    }
})

console.log(proxy.name) //xuke
proxy.name = 'xiaohaha'
proxy.hobby = 'eat'
console.log(object) //{ name: 'xiaohaha', age: 22, hobby: 'eat' }

Set()

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

1.add方法

const s = new Set()

//通过add向Set中添加元素
//由于add()返回的是一个Set对象,所以我们可以链式调用
s.add(1).add(2).add(3)
console.log(s) //Set(3) { 1, 2, 3 }

2.遍历

const s = new Set()
s.add(1).add(2).add(3)

s.forEach(num=>console.log(num)) //1  2  3

for(let num of s){console.log(num)} //1  2  3

3.获取Set长度

const s = new Set()
s.add(1).add(2).add(3)

console.log(s.size) //3

4.has方法

const s = new Set()
s.add(1).add(2).add(3)

//判断Set对象中是否存在某个值
console.log(s.has(22)) //false

5.delete方法

const s = new Set()
s.add(1).add(2).add(3)
//删除Set集合中的元素
s.delete(2)
console.log(s) //Set(2) { 1, 3 }

6.clear方法

const s = new Set()
s.add(1).add(2).add(3)

//清空集合中的元素
// s.clear()
// console.log(s) //Set(0) {}

7.去重

const arr = [2,34,2,4,12,34]

console.log([...new Set(arr)])
console.log(Array.from(new Set(arr)))

Map()

Map 是 ES6 中新增的数据结构,Map 类似于对象,但普通对象的 key 必须是字符串或者数字,而 Map 的 key 可以是任何数据类型...

//初始化
const map = new Map()

1.可以当作普通对象使用

const map = new Map()

map.set('name','xuke')
console.log(map) //Map(1) { 'name' => 'xuke' }

2.键值可以存放对象

const map = new Map()

const obj1 = {
    a:12,
    b:11
}
map.set(obj1,'obj')
console.log(map) //Map(1) { { a: 12, b: 11 } => 'obj' }

3.键值可以存放函数

const map = new Map()

function a(){
    return 100
}

map.set(a,'a')
console.log(map) //Map(1) { [Function: a] => 'a' }

和set一样具有下面的方法 map.has(a) map.delete(a) map.clear()

4.遍历

const map = new Map()
function a(){
    return 100
}
map.set(a,'a')

//方法1
map.forEach((value,key)=>{
    console.log(key) //[Function: a]
    console.log(key()) //100
    console.log(value) //a
})
//方法2
for(let item of map){
     console.log(item) //[ [Function: a], 'a' ]
     console.log(item[0]()) //100
     console.log(item[1])//a
 }

Symbol 数据类型

Symbol是由ES6规范引入的一项新特性,它的功能类似于一种标识唯一性的ID。

1.创建symbol实例

let s1 = Symbol()

在调用Symbol()函数时传入一个可选的字符串参数,相当于给你创建的Symbol实例一个描述信息
let s2 = Symbol('another symbol')

2.有属于自己的symbol类型

typeof s1 // 'symbol'

3.唯一性

let s1 = Symbol()
let s2 = Symbol('another symbol')
let s3 = Symbol('another symbol')

s1 === s2 // false
s2 === s3 // false

4.实现相同的symbol

const sy1 = Symbol.for('xuke')
const sy2 = Symbol.for('xuke')
sy1===sy2 //true

5.应用场景

1.Symbol可用于对象属性的定义和访问

const PROP_NAME = Symbol()
const PROP_AGE = Symbol()

let obj = {
  [PROP_NAME]: "xuke"
}
obj[PROP_AGE] = 22

obj[PROP_NAME] // 'xuke'
obj[PROP_AGE] // 22

2.Symbol类型的key是不能通过Object.keys()或者for...in来枚举的,它未被包含在对象自身的属性名集合(property names)之中。所以,利用该特性,我们可以把一些不需要对外操作和访问的属性使用Symbol来定义。

let obj = {
   [Symbol('name')]: 'xuke',
   age: 18,
   title: 'Engineer'
}
//1.
Object.keys(obj)   // ['age', 'title']

//2.
for (let p in obj) {
   console.log(p)   // 分别会输出:'age' 和 'title'
}
//3.
Object.getOwnPropertyNames(obj)   // ['age', 'title']
//4.
JSON.stringify(obj)  // {"age":18,"title":"Engineer"}

我们es6提供了一些专门针对Symbol的API:

/ 使用ObjectAPI
Object.getOwnPropertySymbols(obj) // [Symbol(name)]

// 使用新增的反射API
Reflect.ownKeys(obj) // [Symbol(name), 'age', 'title']

3.使用Symbol来替代常量

const TYPE_AUDIO = Symbol()
const TYPE_VIDEO = Symbol()
const TYPE_IMAGE = Symbol()

function handleFileResource(resource) {
  switch(resource.type) {
    case TYPE_AUDIO:
      playAudio(resource)
      break
    case TYPE_VIDEO:
      playVideo(resource)
      break
    case TYPE_IMAGE:
      previewImage(resource)
      break
    default:
      throw new Error('Unknown type of resource')
  }
}

4.使用Symbol定义类的私有属性/方法

文件a.js:

const PASSWORD = Symbol()

class Login {
  constructor(username, password) {
    this.username = username
    this[PASSWORD] = password
  }

  checkPassword(pwd) {
      return this[PASSWORD] === pwd
  }
}

export default Login

文件b.js

import Login from './a'

const login = new Login('admin', '123456')

login.checkPassword('123456')  // true

login.PASSWORD  // oh!no!
login[PASSWORD] // oh!no!
login["PASSWORD"] // oh!no!

由于Symbol常量PASSWORD被定义在a.js所在的模块中,外面的模块获取不到这个Symbol,也不可能再创建一个一模一样的Symbol出来(因为Symbol是唯一的),因此这个PASSWORD的Symbol只能被限制在a.js内部使用,所以使用它来定义的类属性是没有办法被模块外访问到的,达到了一个私有化的效果

for...of

1.遍历数组

const arr = [2, 3, 2, 33, 22, 223, 21, 3]

for (let item of arr) {
   console.log(item)
}

2.可用 break 终止循环

const arr = [2, 3, 2, 33, 22, 223, 21, 3]
for (let item of arr) {
    if (item > 10) break
    console.log(item)
}

3.遍历Set()

const set = new Set([2, 3, 1, 2, 34, 3])

for (let item of set) {
    console.log(item) //2 3 1 34
}

4.遍历Map

const map = new Map()
map.set('name','xuke')
map.set('age','12')

for (let item of map){
    console.log(item) //[ 'name', 'xuke' ]  [ 'age', '12' ]
}

//改进
//用数组解构的方式取出key value 方便使用
for (let [key,value] of map){
   console.log(key) //name  age
   console.log(value)//xuke 12
}

ES2016(ES7)

1.数组的includes方法

const arr =[2,3,2,13,23,45]
//原始方法
console.log(arr.indexOf(3)) //1
console.log(arr.indexOf(300)) //-1
//includes方法
console.log(arr.includes(3))//true
console.log(arr.includes(300))//faalse

2.指数运算符

表示210次方:
//原始
console.log(Math.pow(2,10)) //1024

//es2016
console.log(2 ** 10) //1024
console.log(3 ** 10) //59049

ES2017(ES8)

1.object.values

const obj={
   name:'xuke',
   age:22
}

//与object.keys类似,object.keys返回所有`键`组成的数组,
//Object.values返回的对象中的所有`值`组成的数组,

console.log(Object.values(obj)) //[ 'xuke', 22 ]

2.Object.entries

Object.entries,返回对象的键值对组成的组成的数组,

 const obj={
   name:'xuke',
   age:22
}
console.log((Object.entries(obj))) //[ [ 'name', 'xuke' ], [ 'age', 22 ] ]
//遍历方法
for(let [key,value] of Object.entries(obj)){
   console.log(key) //name  age
   console.log(value) //xuke 22
}

3.string方法 填充字符串

padStart()和padEnd()

let str = 'xuke'
//表示用 "=" 填充到 6位长度 的字符串("="在字符串的`前面`填充)
console.log(str.padStart(6,'=')) //==xuke

//表示用 "=" 填充到 6位长度 的字符串("="在字符串的`后面`填充)
console.log(str.padEnd(6,'=')) //xuke==

const str1 = 'xuke'
const str2 = 'is'
const str3 = 'beautiful'

console.log(str1.padStart(26,'-'))//----------------------xuke
console.log(str2.padStart(26,'-'))//------------------------is
console.log(str3.padStart(26,'-'))//-----------------beautiful

4.在函数参数中添加尾逗号

function sum(a,b,){
    return a+b
}
console.log(sum(1,4)) // 5

const array = [2,3,1,5,45,32,]//方便数组的分割
console.log(array) 

5.async/await

async await是promise的语法糖,更加方便的处理异步,增加代码的可读性,详细介绍看我的专本总结文章 Promise,Generator,async/await学习总结基本用法