ES6常用内容

JavaScript 与 ECMAScript 的关系
JavaScript 是 ECMAScript 语法的一种最为流行的具体实现(除此之外比如 Flash 里的 ActionScript 也是一种实现);
JavaScript 有浏览器、Node.js 等多种宿主环境,是一种日常的通称,各种宿主所扩充的 API 有差异,比如浏览器有 document,而 Node.js 有 process,这些在统一语法规范 ECMAScript 中没有规定;
ECMAScript 是ECMA国际组织负责的各种标准之一。

变量声明

  • const:声明一个只读的常量,如果声明的是个对象,是可以改对象的属性,声明后不可以重新赋值
  • let:不允许重复声明,块级作用域,不存在变量提升

数组扩展

遍历

更多遍历方法:对象和数组遍历方法总结

  • includes() 是否包含指定的值

    1
    2
    3
    [1, 2, 3].includes(2)     // true
    [1, 2, 3].includes(4) // false
    [1, 2, NaN].includes(NaN) // true
  • find() 找出第一个符合条件的数组成员

    1
    2
    3
    4
    [1, 5, 10, 15].find(function(value, index, arr) {
    return value > 9;
    })
    //10
  • findIndex() 找出第一个符合条件的数组成员的位置

    1
    2
    3
    4
    [1, 5, 10, 15].findIndex(function(value, index, arr) {
    return value > 9;
    })
    //2
  • for … of 遍历值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
console.log(item);
}
```

### 复制&合并
- concat()
``` js
//复制用法,不会影响原数组
const a1 = [1, 2];
const a2 = a1.concat();
a2[0] = 2;
console.log( a1 ) // [1, 2]

//合并
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
arr1.concat(arr2, arr3);// ES5
  • …扩展运算符
    1
    2
    3
    4
    5
    6
    7
    8
    //复制,不会影响原数组
    const a1 = [1, 2];
    const a2 = [...a1];//或:const [...a2] = a1;
    a2[0] = 100;
    console.log( "a1=",a1," a2=",a2 )

    // ES6 的合并数组
    [...arr1, ...arr2, ...arr3]

对象扩展

遍历

更多遍历方法:对象和数组遍历方法总结

  • Object.keys(obj)
    Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

    1
    2
    Object.keys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
    //["2", "10", "b", "a"]
  • Reflect.ownKeys(obj)
    Reflect.ownKeys返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

    1
    Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })

    首先遍历所有数值键,按照数值升序排列。
    其次遍历所有字符串键,按照加入时间升序排列。
    最后遍历所有 Symbol 键,按照加入时间升序排列。

?.链判断运算符

在读接口时,后端可能会埋个坑,某个对象树给个null,前端没写判断页面就会报错,往往要写长长的判断,爷爷有否?爸爸有否?儿子有否?
如循环时取下面JSON里的 order.hotel.date:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
list: [
{
name: "ken", age: 18, gender: 1,
order: {
shop: [{date: '2020-01-10'}],
hotel: [{date: '2020-01-10'}]
}
},
{name: "blue", age: null, gender: null, order: {shop: [{date: '2020-05-10'}]}},
{name: "jake", age: null, gender: null, order: null}
]
}
{6}
1
2
3
4
5
6
7
8
data.list.forEach((v, i, arr) => {
// console.log(i, v, arr)
//常规写法:
// let orderHotelData = v.order && v.order.hotel && v.order.hotel[0] && v.order.hotel.date || "默认值";
// 链判断写法
let orderHotelData = v.order ?. hotel ?. [0] ?. date || "默认值";
console.log("orderData=", orderHotelData);
});

箭头函数

箭头函数最直观的三个特点:不需要 function 关键字来创建函数,省略 return 关键字,继承当前上下文的 this 关键字。

当函数有且仅有一个参数的时候,是可以省略掉圆括号、{}、return;
不需要参数或需要多个参数,就使用一个圆括号代表参数部分;
如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。
箭头函数没有this,不是所有地方都适用箭头函数的,比如定义对象

1
2
3
4
5
6
7
8
9
10
11
var f = v => v;
console.log(f('ken'))

var showName = name => 'hello ' + name
console.log( showName('ken') );

var showName = (name,age) => 'hello ' + name+ ",you age "+ age
console.log( showName('ken', 18) );

var sum = (num1, num2) => { return num1 + num2; }
console.log( sum(10,18) )

Module语法:export和import

  • 当用export default people导出时,就用 import people 导入(不带大括号)
  • 一个文件里,有且只能有一个export default。但可以有多个export。
  • 当用export name 时,就用import { name }导入(记得带上大括号)
  • 当一个文件里,既有一个export default people, 又有多个export name 或者 export age时,导入就用 import people, { name, age }
  • 当一个文件里出现n多个 export 导出很多模块,导入时除了一个一个导入,也可以用import * as example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//全部导入
import people from './example'

//有一种特殊情况,即允许你将整个模块当作单一对象进行导入
//该模块的所有导出都会作为对象的属性存在
import * as example from "./example.js"
console.log(example.name)
console.log(example.age)
console.log(example.getName())

//导入部分
import {name, age} from './example'

// 导出默认, 有且只有一个默认
export default App

// 部分导出
export class App extend Component {};

本节来源:ES6这些就够了 更多Module语法请参考:Module 的语法

Promise

用同步的语法来写异步的代码,读多个接口的优雅写法 :smile:
每一个 Promise 都有一个 .then 方法,这个方法接受两个参数,第一个是处理 resolved 状态的回调,一个是处理 rejected 状态的回调;
在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数,finally方法的回调函数不接受任何参数。

  • 基本用法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    new Promise(function (resolve, reject) {
    setTimeout(function () {
    let n = Math.ceil(Math.random() * 10);
    if (n >= 5) {
    // console.log("resolve...")
    resolve(n);
    } else {
    // console.log("reject...")
    reject(n);
    }
    }, 0);
    }).then(function (v) {
    console.log('then: ',v);
    }).catch(function (error) {
    console.log('catch: ', error);
    }).finally(() => {
    console.log('finally...' );
    });
  • Promise.all()用法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // 所有图片都加载完再添加到页面
    function loadImg(src){
    return new Promise((resolve,reject)=>{
    let img = document.createElement('img');
    img.src = src;
    img.onload = function(){
    resolve(img);
    };
    img.onerror = function(err){
    reject(err);
    };
    });
    }

    function showImgs(imgs){
    imgs.forEach(function(item){
    document.body.appendChild(item);
    });
    }
    Promise.all([
    loadImg('https://upload.jianshu.io/admin_banners/web_images/3995/97984254f407672e5ca56e4aa66ad9e4330e3e0b.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/1250/h/540'),
    loadImg('https://upload.jianshu.io/admin_banners/web_images/3989/986f00c9a5ab4406b143b8985f925258bba06b9d.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/1250/h/540'),
    loadImg('https://upload.jianshu.io/admin_banners/web_images/3990/4a0679fb9dde465cd13797299699be750382b04c.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/1250/h/540')
    ]).then(showImgs);

async和await

1

ES6内容很多,这里只列一些我高频使用的内容
更多内容看阮一峰老师的电子书:
阮老师的开源ES6第三版电子书