记录之前学es6一些没有细看的部分
解构赋值
基本使用
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
设置默认值:
function f() {
return 'aaa';
}
let [x = f()] = [1]; // x = 1
let [x = f()] = []; // x = 'aaa'
使用场景:
1.交换变量值
let x = 1;
let y = 2;
[x, y] = [y, x]; // [x,y] = [2,1]
2.从函数返回多个值
// 返回一个数组
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
// 返回一个对象
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example(); // import {foo,bar}
3.方便JSON取值
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data} = jsonData;
console.log(id, status,data);
4.方便函数参数的定义
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
5.方便的便遍历Map
// 获取键值对
for (let [key,value] of map) {
// ...
}
// 获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
}
函数拓展
可给函数参数指定默认值,调用时可省略参数。
function fn(par,par2,par3 = 'default'){
return `${par} ${par2} ${par3}`
}
console.log(fn(1,2)) // 1 2 default
和解构赋值结合
function fetch(url, { body = '', method = 'GET', headers = {} }) {
console.log(body) //body
console.log(method); // method
console.log(header) // {}
}
fetch('http://example.com', {body:'body'})
Generator
用async比较多,算是Generator的语法糖,不过是ES7推出,Generator属于ES6标准。
yield
不使用yield的话,就单纯作为一个延时的函数执行。
function* fn() {
console.log('fnfnfn')
}
var generator = fn();
setTimeout(function () {
generator.next()
}, 2000);
使用yield,相当于挂起,需要使用next() 继续执行。
function* func(){
console.log("one");
yield '1';
console.log("two");
yield '2';
console.log("three");
return '3';
}
let f = func();
f.next(); //one
f.next(); //two
next的参数
1.yield表达式本身没有返回值,或者说总是返回undefined。
2. next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
不带参数:
function* fn(){
let c = yield 'c';
console.log(c)
}
let f = fn()
f.next() //开始执行,遇到yield停止 c还没有完成赋值
f.next() // 继续执行赋值 console.log(c) => undefined
带参数:
function* fn(){
let c = yield 'c';
console.log(c)
}
let f = fn()
f.next() //开始执行,遇到yield停止 c还没有完成赋值
f.next('ccccc')
// ccccc作为上一个yield的返回值
// 继续执行赋值 console.log(c) => ccccc
结合异步应用
1.f.next() 返回一个对象,下面这个next执行后返回了 {value:Promise , done:false}
2.then回调中带参数可作为上一个yield的返回值
function getData(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('data1')
},100)
})
}
function* fn(){
let r = yield getData(); // 返回一个Promise
console.log(r); // data12
}
let f = fn()
f.next().value.then(data=>{
// data : data1
// data处理后赋值给r
f.next(data + '2')
})
小demo
- 第一次用url_1请求数据,返回可获取数据的url_2。
- url_2作为next的参数传入,作为上一个yield的返回值®。
- r作为参数再次请求数据,获取到数据。
function getData(url){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
if(url === 'url_1'){
resolve('url_2')
}else if(url === 'url_2'){
resolve('res_data')
}
},100)
})
}
function* fn(url){
let r = yield getData(url); // 返回一个Promise
let r1 = yield getData(r); // r = url_2
}
let f = fn('url_1')
f.next().value.then(data=>{
// data = url_2
f.next(data).value.then(data=>{
console.log(data) // data = res_data
})
})
个人感觉,在next嵌套调用的时候,还是不及async的简洁、易读性强。