一、命令let、const
1.命令let
(1)申明任意数据类型;
(2)申明的是变量,可重新赋任意值;
(3)声明的变量在自身和内部代码块有效;
2.命令const
(1)申明任意数据类型;
(2)申明的是常量,不可重新赋任意值;
(2)声明的变量在自身和内部代码块有效;
二、变量的解构赋值
十三、数据结构Set和Map
es6之前javascript只有Array和Object这两种表示“集合”的数据结构,es6新增的Set和Map可理解为是对Array和Object的补充。
/**
Set:
1.逻辑上的有序集合
2.有size属性
3.所有元素都是唯一的,不会重复存储
*/
let s = new Set();
s.add(1); // Set(2) {1}
s.add(2); // Set(2) {1, 2}
s.add(1); // Set(2) {1, 2}
let a = {name: 'nick'};
let b = {name: 'nick'};
s.add(a); // Set(2) {1, 2, Object}
s.add(a); // Set(2) {1, 2, Object}
s.add(b); // Set(2) {1, 2, Object, Object}
// Array转Set去重
let arr = [...(new Set([1,2,1,3,2]))]; //[1, 2, 3]
/**
api:
s.add(value) 新增
s.delete(value) 删除
s.clear() 清空
s.forEach((value) => {}) 遍历
*/
/**
Map:
1.逻辑上的无序集合
2.拥有清空和遍历功能
*/
let m = new Map();
m.set('name', 'nick'); //Map(1) {"name" => "nick"}
m.set('age', 22); //Map(2) {"name" => "nick", "age" => 22}
/**
api:
m.set(key, value) 新增/修改
m.has(key) 是否存在
m.get(key) 获取值
m.delete(key) 删除
m.clear() 清空
m.forEach((value, key) => {}) 遍历
*/
十四、代理器Proxy和反射器Reflect
let obj = new Proxy({}, {
get: function(target, key, receiver) {
console.log(`get %{key}`);
return Reflect.get(target, key, receiver);
},
set: function(target, key, value, receiver) {
console.log(`set ${key}`);
return Reflect.set(target, key, value, receiver);
}
});
obj.num = 1;
/**
set num
*/
obj.num++;
/**
get num
set num
*/
十五、异步编程Promise
Promise是比回调和事件更合理的异步解决方案。其事例保存着一个再未来结束的任务。
let p = new Promise((resolve, reject) => {
// 异步成功时调用resolve(解决),否则调用reject(拒绝)
setTimeout(() => {
if(true) {
resolve({
state: '成功',
code: 666,
});
} else {
reject({
state: '失败',
code: 555,
});
}
}, 5000);
});
// 绑定成功的回调
p.then((data) => {
console.log(`state = ${data.state}, code = ${data.code}`);
});
// 绑定失败的回调
p.catch((err) => {
console.log(`err = ${err}`);
});
/**
5秒后打印:
state = 成功, code = 666
*/
then和catch都会返回自身的Promise实例,可进行链式调用。Promise实例有三个状态pending(进行中)、fulfilled(已成功)和rejected(已失败)。一旦从pending变为fulfilled或者rejectred,该Promise实例就定型了,状态不会再发生改变。定型后再绑定的then和catch会根据状态立即被调用。
function asyncFun() {
// 将封装了异步操作的promise返回
return new Promise((resolve, reject) => {
// 异步操作,用setTimeout代替
setTimeout(() => {
resolve({
name: 'asyncFun',
state: 'success',
});
}, 1000);
})
}
function fun1() {
// 调用异步函数,为返回的promise添加then回调
return asyncFun().then((data) => {
// 接收到了resolve传入的数据
console.log('fun1 data = ', data); // fun1 data = {name: "asyncFun", state: "success"}
return {
name: 'fun1',
data: data,
}
});
}
function fun2() {
// 链式调用fun1返回的异步promise,添加下一步的then回调
return fun1().then((data) => {
// 接收到了上一次then返回的数据
console.log('fun2 data = ', data); // fun2 data = {name: "fun1", data: {…}}
})
}
// 开始执行
fun2();
十六、迭代器Iterator
迭代器是用于遍历对应数据结构中所有元素的工具,主要提供给for...of使用,如Array的迭代器,任何数组都可以用for...of遍历其所有元素。
迭代器通过其next()函数依次获取元素,Array的迭代器在其Symbol.iterator函数中返回,Symbol.iterator函数也是for...of遍历时用来获取迭代器的函数。
// 获取迭代器
let arr = [2, 1, 0, 3];
let iter = arr[Symbol.iterator]();
console.log(iter.next()); // {value: 2, done: false}
console.log(iter.next()); // {value: 1, done: false}
console.log(iter.next()); // {value: 0, done: false}
console.log(iter.next()); // {value: 3, done: false}
console.log(iter.next()); // {value: undefined, done: true}
// 为Object对象添加迭代器
let obj = {
key1: 0,
key2: 'nick',
key3: true,
key4: () => {},
[Symbol.iterator]: function() {
const keys = Object.keys(this);
let index = 0;
return {
next: () => {
let i = index++;
let value = this[keys[i]];
return {
value: value,
done: i >= keys.length,
}
};
}
},
};
// 获取到迭代器
let iter = obj[Symbol.iterator];
iter.next(); // {value: 0, done: false};
iter.next(); // {value: "nick", done: false}
iter.next(); // {value: true, done: false}
iter.next(); // {done: false, value: ƒ}
iter.next(); // {value: undefined, done: true}
// 使用for...of遍历
for (const value of obj) {
console.log(value);
}
/**
0
nick
true
() => {}
*/
十七、Generator函数
Generator(生产者)是一种特殊的函数,通过function*声明,是ES6提供的一种异步解决方案。Generator函数调用后返回一个迭代器,迭代器的next()每调用一次,Generator函数就顺序向下执行一段,直到return。每次next()的执行范围通过yield(出产)划分,即执行到每个yield处暂停,并返回yield后面的值。第二次调用next()时传入的参数将替换上一次yield后面的值。
function* fun(){
yield 'hello';
yield 'generator';
return 'end';
}
let iter = fun();
iter.next(); // {value: "hello", done: false}
iter.next(); // {value: "generator", done: false}
iter.next(); // {value: "end", done: true}
根据Generator函数返回一个迭代器的特点与任意对象的Symbol.iterator函数相同,那么我们可以使用Generator函数实现Symbol.iterator。
obj = {
key1: 1,
key2: 2,
key3: 3,
[Symbol.iterator]: function* () {
const keys = Object.keys(this);
for (const key of keys) {
yield this[key];
}
}
}
十八、异步async
async是Generator的语法糖,用async代替function*,用await代替yield。区别在于async函数自带执行器,不需要像Generator一样返回一个迭代器,手动调用next。另外,async调用后会自动返回一个Promise实例,当async中所有的异步任务都结束时该Prpmise实例结束。
async function fun() {
console.log('start');
await 1;
console.log('progress 1');
await 2;
console.log('progress 2');
}
const prom = fun();
/**
start
progress 1
progress 2
*/
prom.then(() => {
console.log('fun over');
});
// fun over
异步操作
function task() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('test over');
resolve();
}, 2000);
});
}
async function asyncFun() {
console.log("asyncFun1");
await task();
console.log("asyncFun2");
await task();
console.log("asyncFun3");
}
function fun() {
console.log("start");
asyncFun().then(() => {
console.log('async over');
});
console.log("start");
}
/**
start
asyncFun1
end
...等待2秒
test over
asyncFun2
...再等待2秒
test over
asyncFun3
async over
*/
参考文献:《ES6标准入门》(第3版)