ES6新特性速查表

这份文档整理了博主在前端项目中经常需要查阅ES6+的代码,并作出相应解释以及给出最新的代码示例。除此之外,博主还会偶尔会写上一些我的小技巧,也会注意提示这只是我的个人提议。

你或许会因为不熟悉当前一些新的代码库(例如 React)所用到的 JavaScript 概念,而很难上手这些新框架。所以本文档的目的并非从零教你 JavaScript,而是帮助已经有一定编程基础的你。

注:这篇文档里提到的大多数概念来自于目前最新的 JavaScript(ES2015,即 ES6),你可以在 这里 查看新增的特性,网站做得很棒。

常用语法

  • 变量声明
let             // 块级作用域变量声明 代替了var声明
const           // 常量声明 在开发中一般不让修改的值使用const声明
  • 解构赋值
// 结构赋值可以用于数组 也可以用于对象
let [a, b, c] = [1, 2, 3];
let [head, ...tail] = [1, 2, 3, 4];         // tail === [2,3,4]
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
  • 扩展运算符

// 可以将一个数组的元素放入到另一个数组 组成一个新的数组 并且地址引用不同 一般用于创建的数据 解决地址引用问题
const arr = [1,2,3];

const brr = [6, ...arr];
  • 模版字符串
// 可以在字符串中正常使用变量
const name = '憧憬';
let str = `你好${name}!`;
  • 箭头函数
// 新的函数声明方式 可以解决this指向问题。默认绑定上下文this
const f = () => {
}
  • 函数多参数传递 rest参数
function add(...values) {
    // 不使用传统的arguments对象
    // values === [1,2,3]
}

add(1,2,3);
  • 将对象转为数组 Array.from()
let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};

Array.from(arrayLike); // ['a', 'b', 'c']
  • 判断数组是否包含给定值 includes
[1, 2, 3].includes(2)     // true
  • 数组维度转换 flat
//转一维
[1, 2, [3, 4]].flat() // [1, 2, 3, 4]
  • 获取对象的原型对象 super
const proto = {
  foo: 'hello'
};

const obj = {
  foo: 'world',
  find() {
    return super.foo;
  }
};

Object.setPrototypeOf(obj, proto);
obj.find() // "hello"
  • 链式判断运算符 很常用
const firstName = (message
  && message.body
  && message.body.user
  && message.body.user.firstName) || 'default';
  
const firstName = message?.body?.user?.firstName || 'default';

// 上面代码使用了?.运算符,直接在链式调用的时候判断,左侧的对象是否为null或undefined。如果是的,就不再往下运算,而是返回undefined。

a?.b
// 等同于
a == null ? undefined : a.b
  • Null 判断运算符 ?? 很常用
// 以前
const headerText = response.settings.headerText || 'Hello, world!';
// 现在
const headerText = response.settings.headerText ?? 'Hello, world!';
  • 对象合并 Object.assign
// 解决同一对象地址引用问题 如果键相同 后者覆盖前者
const target = { a: 1 };

const source1 = { b: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
  • set操作
// 主要集合操作 去重
const set = new Set([1, 2, 3, 4, 4]);
set.add();  // 添加某个值,返回 Set 结构本身。
set.delete(); // 删除某个值,返回一个布尔值,表示删除是否成功。
set.has();  // 返回一个布尔值,表示该值是否为Set的成员。
set.clear(); // 清除所有成员,没有返回值。
set.size    // 获取set的成员数量
  • map操作
// 对 对象的扩展 对象以前键是不能使用对象的
const m = new Map();
const map = new Map();
map.set('foo', true); // 写入值到map里面
map.size    // 获取map成员数量
map.get('key')   // 获取map成员值
map.has('key');
map.delete('key');
map.clear();

高阶函数

  • map 对数组的每一个成员进行遍历, 并将返回值 组成一个新的数组
const arr = [1,2,3];

const brr = arr.map((item) => {
    return item*2;
});

// brr === [2,4,6]
  • filter 对数组进行遍历 给定条件 条件为真保留 否则去掉 返回一个新的数组
const arr = [1,2,3];

const brr = arr.filter((item) => {
    return item > 1;
});

// brr === [2,3]
  • reduce 用于函数的 compose
// item为初始值, [[]], 循环每次返回值都会作为下一次的item 
// val为当前循环的值
// index为当前循环的索引
// brr为循环的数组
const arr = [1,2,3,4];
arr.reduce((item, val, index, brr) => {
    item[0].push(val); 
    return item;
}, [[]]);
  • forEach 只是对数组进行遍历
arr.forEach((item) => {
    console.log("aoppp.com");
});
  • every 对数组中每一项运行给定函数,如果该函数对每一项返回true,则返回true。
const arr = [ 1, 2, 3, 4, 5, 6 ]; 

arr.some((item, index, array) => { 
    return item > 3; 
})); // false
  • some 对数组中每一项运行给定函数,如果该函数对任一项返回true,则返回true。
const arr = [ 1, 2, 3, 4, 5, 6 ]; 

arr.some((item, index, array) => { 
    return item > 3; 
})); // true
  • find
// 找出第一个符合条件的数组成员
[1, 5, 10, 15].find(function(value, index, arr) {
  return value > 9;
}) // 10
  • findIndex
// 数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
[1, 5, 10, 15].findIndex(function(value, index, arr) {
  return value > 9;
}) // 2
  • Promise 异步操作
const promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then((res) => {
    // 可以获取到promise resolve的值
}).catch(() => {
    // 可以获取 promise reject的值
}).finally(() => {
    // 每次都会执行这个
});
  • Promise.all() 多个异步
// 执行多个promise操作
Promise.all([p1, p2, p3]);

// (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

// (2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
  • Promise.race() 多个异步操作 谁先返回获取谁
const p = Promise.race([p1, p2, p3]);
// 上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
  • Promise.allSettled 多个异步 强制等待
const promises = [
  fetch('/api-1'),
  fetch('/api-2'),
  fetch('/api-3'),
];
// Promise.allSettled()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束
  • Async + await 多个异步变同步
const asyncReadFile = async function () {
  const f1 = await readFile('/etc/fstab');      // 利用await就可以将异步 变成同步的
  const f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};
  • export + import 模块导入导出
// ./profile.js
const firstName = 'Michael';
const lastName = 'Jackson';
const year = 1958;
export { firstName, lastName, year };


// main.js
import { firstName as newName, lastName, year } from './profile.js';

// 导入时还可以利用as起别名 避免变量冲突


// 从前面的例子可以看出,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。
// 默认导出 export-default.js
export default function () {
  console.log('foo');
}


// import-default.js
import customName from './export-default';
customName(); // 'foo'

本文为作者原创,手码不易,允许转载,转载后请以链接形式说明文章出处。

您的支持是对我最大的鼓励!

发表于: 作者:憧憬。
关注互联网以及分享全栈工作经验的原创个人博客和技术博客,热爱编程,极客精神
Github 新浪微博 SegmentFault 掘金专栏