ES6 Exploring 笔记

Core ES6 feature

exploringjs笔记

  1. var to let/const

优先使用const, 只要值不再改变的变量就用const;否则用let;避免用var

  1. IIFEs to blocks

如果在ES5中想限制变量在一个块作用域中,你需要使用一个叫做IIFE(Immediately-Invoked Function Expression)的模式:

1
2
3
(function(){
var tmp...
}());

在ES6中只需要使用一个块声明或者一个const声明就行了:

1
2
3
{
let tmp = ...
}
  1. 字符串插值

避免字符串拼接, 以及多行字符串。

  1. 函数表达式 to 箭头函数
1
2
3
4
5
6
7
function UiComponent() {
var button = document.getElementById('mybutton');
button.on('click', ()=>{
console.log('CLICK');
this.handleClick(); // 这里的this是UiComponent的this,还不知道为什么
});
}
  1. 处理多个返回值

使用数组返回多个值

1
const [, year, month, day] = /^(\d\d\d\d)-(\d\d)-(\d\d)$/.exec('2019-12-21');

上面例子中数组的第一个逗号是为了跳过数组第一个元素,因为/^(\d\d\d\d)-(\d\d)-(\d\d)$/.exec('2019-12-21')
返回的是["2019-12-21", "2019", "12", "21"]

使用objects返回多个值

所谓的解构Destructuring

1
const {writable, configurable} = Object.getOwnPropertyDescriptor(foo, 'foo')
  1. 使用for-of替换forforEach

    for循环的优势是可以被中断(break),forEach简洁, 而for-of兼顾了for,forEach的优点

如果同时需要索引和值,可以使用Arrayentries:

1
2
3
for(const [index, elem] of arr.entries()) {
console.log(`${index}, ${elem}`);
}
  1. 使用参数默认值

    ES6中只有undefined才能触发默认值

  2. 命名参数

通过字面对象实现(所谓的可选对象模式

1
function selectEntries( { start=0, end=1, step=1 }) {}
  1. 剩余参数(Rest Parameters)

    使用...操作符实现

    1
    2
    3
    4
    5
    6
    function logAllArguments(...args) {
    for (const arg of args) {
    console.log('---');
    console.log(arg);
    }
    }

可选参数:

1
2
3
function selectEntries({ start=0, end=-1, step=1 } = {}) {
···
}
  1. 展开操作符...替换apply()

在ES5中,将数组转换为参数使用apply(), ES6中可以使用...

1
2
3
4
5
6
7
Math.max(...[1, 21, 2, -10])

let arr1 = ['a', 'b'];
const arr2 = ['c', 'd'];

arr1.push.apply(arr1, arr2); // arr1=['a', 'b', 'c', 'd'] ES5
arr1.push(...arr2); // arr1=['a', 'b', 'c', 'd'] ES6
  1. 展开操作符...替换concat()
1
2
3
4
const ar1 = ['a', 'b'];
const ar2 = ['c'];
const ar3 = ['d'];
console.log([...ar1, ...ar2, ...ar3]);
  1. 在字面对象中,用定义方法的方式替换函数表达式

  2. 类替换构造函数(From constructors to classes)

Base classes

1
2
3
4
5
6
7
8
9
class Person {
constructor(name) {
this.name = name;
}

describe() {
return 'Person called' + this.name;
}
}

Derived classes

1
2
3
4
5
6
7
8
9
10
class Employee extends Person {
constructor(name, title) {
super(name);
this.title = title;
}

describe() {
return super.describe() + '(' + this.title + ')';
}
}
  1. 使用继承Error类的方式的替换自定义error构造函数
1
class MyError extends Error {}
  1. 使用内置的Map数据结构
1
2
3
4
5
const map = new Map();
function countWords(word) {
const count = map[word] || 0;
map.set(word, count + 1);
}

ES5:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var dict = Object.create(null);
function countWords(word) {
var escapeKey = escapeKey(word);
if(escapeKey in dict) {
dict[escapeKey]++;
} else {
dict[escapeKey] = 1;
}
}

function escapeKey(key) {
if(key.indexOf('__proto__') === 0) {
return key + '%';
} else {
return key;
}
}

而且Map的key可以不是字符串

  1. 新的字符串方法

    • startsWith()
    1
    2
    str.indexOf(s) === 0; // ES5
    str.startsWith(s); // ES6
    • endsWith()

    • includes()

      1
      2
      str.indexOf('s') >=0; // ES5
      str.includes('s'); // ES6
    • repeat()

      1
      2
      new Array(3+1).join('#'); // ES5, hack
      '#'.repeat(3); // ES6
  2. 新的数组方法

    • Array.prototype.indexOf -> Array.prototype.findIndex
      1
      2
      3
      4
      const arr = [1, NaN];

      arr.indexOf(NaN); // -1
      arr.findIndex( x=> Number.isNan(x))); // 1
    • Number.isNaN() 是比 isNaN() 更安全的方法,因为isNaN会强制转型*
      1
      2
      isNaN('a'); // true
      Number.isNaN('a'); // false
    • Array.prototype.slice() -> Array.from(),或者使用展开操作符(...)

    在ES5中,Array.prototype.slice方法用来将类数组对象转换为数组;
    如果一个值是可迭代的,也可以使用展开操作符来转换

    1
    2
    3
    var arr1 = Array.prototype.slice.call(arguments); // ES5
    const arr2 = Array.from(arguments)
    const arr3 = [...arguments]
    • apply() -> Array.fill()

    ES5中可以是用applyhack方式来创建任意长度的undefined数组

    ES5:

    1
    Array.apply(undefined, new Array(2));

    ES5:

    1
    new Array(2).fill(undefined)
  • CommonJS modules -> ES6 modules
1
import * from 'lib'

Single exports

1
export default function() {}

Modules

  1. Single export

导出默认匿名对象不需要分号

1
2
export default function() {} // 没有分号
export default class {...} // 没有分号
  1. Modules是单例

即使被导入多次,只有一个实例存在

  1. ECMAScript 5 modules systems

    • CommonJS Modules

      主导该规范实现的是NodeJS

      特点

      • 紧凑语法(Compact syntax)
      • 服务器端同步加载
    • Asynchronous Module Definition(AMD)

      RequireJS是该规范最流行的实现

      特点

      • 稍比较复杂的语法,在适使用eval()的情况下使AMD工作
      • 为服务器端和浏览器端异步加载设计
  2. ECMAScript 6 modules

两种导出方法:命名导出(一个模块可以导出多个),default exports(每个模块导出一个),
可以混用,但是尽量分开。