ES6-Symbol&promise、generator、async/await&rest参数


ES6 Symbol

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。

基本用法
Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分。

1
2
3
4
5
6
7
let sy = Symbol("KK");
console.log(sy); // Symbol(KK)
typeof(sy); // "symbol"

// 相同参数 Symbol() 返回的值不相等
let sy1 = Symbol("kk");
sy === sy1; // false

Symbol 类型的注意点?

  1. Symbol 函数前不能使用 new 命令,否则会报错。
  2. Symbol 函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
  3. Symbol 作为属性名,该属性不会出现在 for…in、for…of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。
  4. Object.getOwnPropertySymbols 方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。
  5. Symbol.for 接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。
  6. Symbol.keyFor 方法返回一个已登记的 Symbol 类型值的 key。

promise、generator、async/await

promise

优点:解决了回调地狱的问题
缺点:无法取消 Promise ,错误需要通过回调函数来捕获

generator

生成器内部的代码是以自然的同步 / 顺序方式表达任务的一系列步骤

async/await

优点:代码清晰,不用像 Promise 写一大堆 then 链,处理了回调地狱的问题

缺点:await 将异步代码改造成同步代码,如果多个异步操作没有依赖性而使用 await 会导致性能上的降低。

  1. async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。

await 关键字仅在 async function 中有效。如果在 async function 函数体外使用 await ,你只会得到一个语法错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function testAwait(){
return new Promise((resolve) => {
setTimeout(function(){
console.log("testAwait");
resolve();
}, 1000);
});
}

async function helloAsync(){
await testAwait();
console.log("helloAsync");
}
helloAsync();
// testAwait
// helloAsync

rest参数

  1. ES6引入rest 参数,用于获取函数的实参,用来代替arguments

使用…rest形式设置剩余形参,支持无限参数
// 剩余参数,转化成数组

1
2
3
4
5
const restParams = function(...args) {
console.log(args.toString());//1, 2, 3, 4, 5
}

restParams(1, 2, 3, 4, 5)
  1. rest 参数必须要放到参数最后

  2. […]扩展运算符能将[数组] 转换为都好分隔的参数序列

  3. 数组的合并

1
2
3
4
5
6
7
<script>
const A = ["a", "b"];
const B = ["1", "2"];
// const C = A.concat(B); // ["a", "b", "1", "2"]
const C = [...A, ...B]; //["a", "b", "1", "2"] 能展开
console.log(C);
</script>
  1. 数组的克隆
1
2
3
const A = ["a", "b"];
const C = [...A]; //["a", "b"]
console.log(C);
  1. 将伪数组转为真正的数组
1
2
3
const divs = document.querySelectorAll("div");
const divArr = [...divs];
console.log(divArr); //[div, div, div]

语法糖

之所以叫「语法」糖,不只是因为加糖后的代码功能与加糖前保持一致,更重要的是,糖在不改变其所在位置的语法结构的前提下,实现了运行时等价。可以简单理解为,加糖后的代码编译后跟加糖前一毛一样。

之所以叫语法「糖」,是因为加糖后的代码写起来很爽,包括但不限于:代码更简洁流畅,代码更语义自然... 写得爽,看着爽,就像吃了糖。效率高,错误少

PS: 据说还有一种叫做「语法盐」的东西,主要目的是通过反人类的语法,让你更痛苦的写代码。其实它同样能达到避免代码书写错误的效果,但编程效率应该是降低了,毕竟提高了语法学习门槛,让人咸到忧伤…

我觉着 js 里的对象原型继承有点「咸」,不然 ES6 也不会急着加糖(纯吐槽)

最基本的,for循环就是一个语法糖:

1
2
3
for (var i = 0; i < 5; i++){
...
}

而这个实际上跟while没啥区别:

1
2
3
4
5
var i=0;
while (i < 5){
...
i++;
}

简单说,语法糖就是为了避免coder出现错误并提高效率的语法层面的一种优雅的解决方案。

参考文章

promise、generator、async/await

ES6 async 函数

什么是语法糖?


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!