es6语法精要

介绍

目前浏览器和教科书中学到的大量 js 语法,是所谓的 ES5 版本。
ES5 之前,一直是这样命名的:

  • Standard ECMA-262, 1st Edition(其实第一个版本是没有版本号的)
  • Standard ECMA-262, 2nd EditionStandard ECMA-262
  • 3rd EditionStandard ECMA-262 5th (这就是 ES5)
  • EditionStandard ECMA-262 5.1 Edition

其中后面 1st,2nd,5th 是版本号。ES5 之后,标准的命名改了,加上了年份,ES6 就变成叫 ECMAScript® 2015 Language Specification, ES7 就是 ECMAScript® 2016 Language Specification。所以大家直接叫她的年份名字就行了。

现在已经出 ES8 了,他们的名称对应如下:

  • ES6 (ES2015)
  • ES7 (ES2016)
  • ES8 (ES2017)

总之,ES2015 或者更新的 ES 语法标准 提供了许多新的语法和编程特性以提高 JavaScript 的开发效率和体验

ES7 和 ES8

http://www.jianshu.com/p/a138a525c287

模块化

1
2
3
4
5
// 导入语法
import mod from "./mod.js";

// 导出语法
export default mod = {};

这篇文章记录了 ES module 的发展和讨论历史,以及如何最终决定使用 .mjs 扩展名的方式来兼容 commonjs 和 esmodule 模块的加载。
https://segmentfault.com/a/1190000004940294

es6 的模块化,在 Node 中一直没有实现。如果希望使用的话,需要使用 babel 进行预编译来实现。

箭头函数

箭头函数使得我们编写代码更加简洁。

1
2
3
4
5
6
const test = (param) => console.log(param);
// 如果参数多一些,就要给形参加上括号. 如果函数体不止一句,则需要加大括号
const test = (param1, param2) => {
console.log(param2);
console.log(param1);
};

箭头函数一个重要的特性是其 this 会引用其上层作用域的 this (即箭头函数定义所在的作用域的 this)

属性简洁表示法

如果要把一个变量赋值给一个对象作为属性,且你希望就用变量名字当做属性名。此时,可以直接使用

1
2
const foo = 'bar';
const baz = {foo};

则 baz 变量实际上为:

1
{foo: foo}

扩展运算符

1
2
3
let z = { a: 3, b: 4 };
let n = { ...z };
n; // { a: 3, b: 4 }

他实现的是浅复制,并不是将 z 对象的指针赋值给 n。其含义类似如下代码:

1
2
3
let aClone = { ...a };
// 等同于
let aClone = Object.assign({}, a);

应用场景:

  • 将多个大对象赋值给一个需要分解后属性的变量。比如 Vue 的 computed 属性,除了自己定义一些属性之外,有时需要把 vuex 里的 state 映射到这里,此时可以利用扩展运算符:
1
2
3
4
5
6
7
computed: {
yourProperty () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}
  • 修改已有对象的某个属性
1
2
3
4
let newVersion = {
...previousVersion,
name: "New Name", // Override the name property
};

这样 previousVersion 表示已有的对象,则这种写法可以用 name 去修改 previousVersion 这个对象里的 name 属性

  • 接收参数时,给参数设置默认值
1
let aWithDefaults = { x: 1, y: 2, ...options };

如果 options 里面没有设置 x 和 y,则 x 和 y 的默认值为 1 和 2. 它等同于:

1
2
3
let aWithDefaults = Object.assign({}, { x: 1, y: 2 }, a);
// 等同于
let aWithDefaults = Object.assign({ x: 1, y: 2 }, a);
  • 扩展对象到

模块

ES module 是新一代的模块化方法,它主张静态解析的能力。而不像以前要引用另外一个模块的话,需要引用另外一个模块导出的完整对象。有了 esmodule,我们可以指定要 import 哪个方法,哪个属性。从而在编译期间就能缩减加载内容。基于此, export 也应该具备导出单个属性和方法的能力。下面我们看下例子:

1
2
3
4
5
6
7
// a.js
const a = {};
export default a; // 将 a 作为本模块的默认导出
const b = {};
const c = function () {};
export { b, c }; // 将 b 和 c 两个属性导出
export const d = {}; // 将属性 d 导出

我们在 a.js 里面使用 默认导出,单独导出 等方式导出了多个变量。下面我们在 b.js 里面把他们导入进来

1
2
3
4
// 导入 a
import a from "a.js"; // default导出只有一个,因此我们导入时可以改变名字: import xx from 'a.js'也可以
// 导入b c
import { b, c } from "a.js";

class 类的新写法

首先,我们知道 ES6 中新增了 class 关键字,允许我们像其他面向对象的语言一样来定义类(实际上它是原型写法的语法糖)。

另外,有了 class 之后,我们的属性不再是只能在构造函数或实例中创建,而是可以在声明类的时候便声明属性。如下 _count 属性:

1
2
3
4
5
6
7
8
9
10
class IncreasingCounter {
_count = 0;
get value() {
console.log("Getting the current value!");
return this._count;
}
increment() {
this._count++;
}
}

这样我们可以把类中所有属性都定义在类的声明前面,一目了然。

Refer

给 JavaScript 初心者的 ES2015 实战