记录一些迁移到 ES6 、ES7 的笔记,主要参考了 ECMAScript 6 入门
新增了很多内容,这里只记录常用的。
变量声明
ES6 新增了两个变量声明的关键词 let
和 const
let
用于代替 var
。
let
不会像 var
那样声明为全局变量
1 2 3 4 5 6 7
| { let a = 10; var b = 1; }
a b
|
所以也不需要 IIFE 了。因为 let
声明相当于块级作用域
1 2 3 4 5 6 7
| function f1() { let n = 5; if (true) { let n = 10; } console.log(n); }
|
const
用于声明只读的常量
1 2 3 4 5
| const PI = 3.1415; PI
PI = 3;
|
详情
解构
ES6 增加了变量解构赋值
1 2 3 4 5
| var a = 1; var b = 2; var c = 3;
let [a, b, c] = [1, 2, 3];
|
解构赋值很灵活
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| let [foo, [[bar], baz]] = [1, [[2], 3]]; foo bar baz
let [ , , third] = ["foo", "bar", "baz"]; third
let [x, , y] = [1, 2, 3]; x y
let [head, ...tail] = [1, 2, 3, 4]; head tail
let [x, y, ...z] = ['a']; x y z
|
解构赋值可用于多值返回,参数解构等
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 example() { return [1, 2, 3]; } let [a, b, c] = example();
function example() { return { foo: 1, bar: 2 }; } let { foo, bar } = example();
function f([x, y, z]) { ... } f([1, 2, 3]);
function f({x, y, z}) { ... } f({z: 3, y: 2, x: 1});
|
字符串
字符串操作新增了很多方法,主要说几个常用的。
includes()
判断是否包含特定字符串
startsWith()
判断是否以特定字符串开头
endsWith()
判断是否以特定字符串结尾
1 2 3 4 5 6 7 8 9
| var s = 'Hello world!';
s.startsWith('Hello') s.endsWith('!') s.includes('o')
s.startsWith('world', 6) s.endsWith('Hello', 5) s.includes('Hello', 6)
|
ES6 还新增了模板字符串,用\`
包裹 。模板字符串中的空格和换行都会保留。
1 2
| console.log(`string text line 1 string text line 2`);
|
还可以用作插值表达式
1 2 3
| var name = "Bob", time = "today"; `Hello ${name}, how are you ${time}?`
|
数值
ES6 新增二进制和八进制的表示法
1 2
| 0b10000000000 === 1024 0o2000 === 1024
|
还新增了一些处理数字的方法,常用的有
Number.isNan()
判断是否为 NaN
1 2 3 4 5 6 7 8 9
| NaN === NaN Number.isNaN(NaN)
Number.isNaN(15) Number.isNaN('15') Number.isNaN(true) Number.isNaN(9/NaN) Number.isNaN('true'/0) Number.isNaN('true'/'true')
|
Math.truct()
截断小数
1 2 3 4 5 6 7 8 9
| Math.trunc(4.1) Math.trunc(4.9) Math.trunc(-4.1) Math.trunc(-4.9) Math.trunc(-0.1234) Math.trunc('123.456') Math.trunc(NaN); Math.trunc('foo'); Math.trunc();
|
Math.sign()
判断正负
1 2 3 4 5 6 7
| Math.sign(-5) Math.sign(5) Math.sign(0) Math.sign(-0) Math.sign(NaN) Math.sign('foo'); Math.sign();
|
此外还新增了指数运算符 **
1 2 3 4 5 6
| 2 ** 2 2 ** 3
let a = 2; a **= 2;
|
数组
数组也新增了方法,常用的有
Array.from()
用于将类数组转为数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 };
var arr1 = [].slice.call(arrayLike);
let arr2 = Array.from(arrayLike);
let ps = document.querySelectorAll('p'); Array.from(ps).forEach(function (p) { console.log(p); });
function foo() { var args = Array.from(arguments); }
|
Array.of()
将一组值转化为数组
1 2 3
| Array.of(3, 11, 8) Array.of(3) Array.of(3).length
|
find()
返回符合条件的元素
1 2
| [1, 4, -5, 10].find((n) => n < 0)
|
findIndex()
返回符合条件的元素索引
1 2 3
| [1, 5, 10, 15].findIndex(function(value, index, arr) { return value > 9; })
|
所以以后使用 indexOf
时优先考虑使用 includes()
、find()
、findIndex()
函数声明
ES6 新增了胖箭头函数用于声明 $\lambda$ 表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var f = v => v;
var f = function(v) { return v; };
var f = () => 5;
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
var sum = function(num1, num2) { return num1 + num2; };
|
使用箭头函数还有一个好处就是不用手动绑定 this
。
ES6 新增了对参数默认值的支持
1 2 3 4 5 6 7
| function log(x, y = 'World') { console.log(x, y); }
log('Hello') log('Hello', 'China') log('Hello', '')
|
可以和解构赋值搭配使用
1 2 3 4 5 6 7 8
| function foo({x, y = 5}) { console.log(x, y); }
foo({}) foo({x: 1}) foo({x: 1, y: 2}) foo()
|
还新增了不定参数的支持
1 2 3 4 5 6 7 8 9 10 11
| function add(...values) { let sum = 0;
for (var val of values) { sum += val; }
return sum; }
add(2, 5, 3)
|
新增扩展运算符,将数组化为元素序列
1 2 3 4 5 6 7 8
| console.log(...[1, 2, 3])
console.log(1, ...[2, 3, 4], 5)
[...document.querySelectorAll('div')]
|
可以用于合并数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| [1, 2].concat(more)
[1, 2, ...more]
var arr1 = ['a', 'b']; var arr2 = ['c']; var arr3 = ['d', 'e'];
arr1.concat(arr2, arr3);
[...arr1, ...arr2, ...arr3]
|
还可以搭配解构赋值使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| let a = list[0], rest = list.slice(1)
let [a, ...rest] = list
const [first, ...rest] = [1, 2, 3, 4, 5]; first rest
const [first, ...rest] = []; first rest
const [first, ...rest] = ["foo"]; first rest
|
对象
ES6 新增对象声明语法糖 class
用传统的原型链声明一个对象
1 2 3 4 5 6 7 8 9 10
| function Point(x, y) { this.x = x; this.y = y; }
Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; };
var p = new Point(1, 2);
|
用 class
语法糖
1 2 3 4 5 6 7 8 9 10 11
| class Point { constructor(x, y) { this.x = x; this.y = y; }
toString() { return '(' + this.x + ', ' + this.y + ')'; } }
|
还可以使用 extends
来继承,使用 super()
调用父类函数
1 2 3 4 5 6 7
| class A {}
class B extends A { constructor() { super(); } }
|
新增了一些简化表示法
属性简写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var foo = 'bar'; var baz = {foo}; baz
var baz = {foo: foo};
function f(x, y) { return {x, y}; }
function f(x, y) { return {x: x, y: y}; }
f(1, 2)
|
方法简写
1 2 3 4 5 6 7 8 9 10 11 12
| var o = { method() { return "Hello!"; } };
var o = { method: function() { return "Hello!"; } };
|
详情
Promise
ES6 Promise
迭代
新增了 for ... of
迭代,相当于其他语言的 for each
1 2 3 4 5 6 7 8 9
| var arr = ['a', 'b', 'c', 'd'];
for (let a in arr) { console.log(a); }
for (let a of arr) { console.log(a); }
|
还可搭配新增的 entries()
、key()
、value()
使用
1 2 3 4 5 6 7
| let arr = ['a', 'b', 'c']; for (let pair of arr.entries()) { console.log(pair); }
|
代码风格
两空格缩进,不添加分号。