Set用法
类似于数组,但是成员的值都是唯一的,没有重复的值。
只有NaN和 === 不一样 其他都是一样做比较的
var set = new Set(NaN)
set.add(NaN);
set // Set {NaN}
set.size //1
set.delete() //删除某个值 返回值表示是否删除成功
set.has() // 返回布尔值 表示是否有某个值
set.clear() // 清空所有项 没有返回值
[...new Set('ababbc')] // ['a','b','c']
也可以使用Array.from解开Set实例
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) { console.log(item);}// red green blue
for (let item of set.values()) { console.log(item);}// red green blue
for (let item of set.entries()) { console.log(item);}// ["red", "red"] ["green", "green"] ["blue", "blue"]
Set.prototype[Symbol.iterator] === Set.prototype.values // true 所以可以用for...of循环得到每一项值
for (let i of set) {
console.log(i);//获取set内部的每一项
}
set.forEach((value, key) => console.log(key + ' : ' + value)) // key和value 值一样
可以把Set实例看做数组 进行map和filter操作 和数组用法类似
const p = [item,item,...] // item必须是对象也可以是数组 否则报错
const set = new WeakSet(b);
set.add(value)
set.delete(value)
set.has(value)
set.size // undefined 没有size和forEach
set.forEach // undefined
Map用法
DOM 节点作为对象data的键,但是由于对象只接受字符串作为键名,所以element被自动转为字符串[object HTMLDivElement]。
const data = {};
const element = document.getElementById('myDiv');
data[element] = 'metadata';
data['[object HTMLDivElement]'] // "metadata"
为了解决这个问题,ES6 提供了 Map 数据结构。它类似于对象
var obj = {}
var map = new Map([
[obj, '111'],
['key2', '222']
]);
map.get(obj) //111
//有这些方法 has get set delete clear size forEach keys values entries
for...map.keys() => 第一项是obj 也可以使用 [...map.keys()]
for...map.values() => 第一项是"111" 也可以使用 [...map.values()]
for...map.entries() => 第一项是[obj,'111'] 也可以使用 [...map.entries()]
for...map.forEach(value, key) => 第一项 value为'111' key为obj
WeakMap只接受对象作为键名 WeakMap 里面对element的引用就是弱引用,不会被计入垃圾回收机制。
只有这些方法 has get set delete
const wm1 = new WeakMap();
Promise
//请求某个table数据
function requestTableList(){
var p = new Promise((resolve, reject) => {
//去后台请求数据,这里可以是ajax,可以是axios,可以是fetch
resolve(res);
});
return p;
}
//延时函数,用于给请求计时 10s
function timeout(){
var p = new Promise((resolve, reject) => {
setTimeout(() => {
reject('请求超时');
}, 10000);
});
return p;
}
Promise.race([requestTableList(), timeout()]).then((data) =>{
//进行成功回调处理
console.log(data);
}).catch((err) => {
// 失败回调处理
console.log(err);
});
function promiseClick1(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
function promiseClick2(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
function promiseClick3(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
Promise
.all([promiseClick3(), promiseClick2(), promiseClick1()])
.then(function(results){
console.log(results);
})
class继承
父辈为超类 子辈为子类 子类继承超类 调用super其实是调用超类的构造函数方法
class A {
constructor(a) {
this.a = a;
}
}
class B extends A {
constructor(a, b) {
super(a);
this.b = b;
}
}
class C extends B {
constructor(a, b, c) {
super(a, b);
this.c = c;
}
}
console.log(new C(1, 2, 3))//C { a: 1, b: 2, c: 3 }
Promise并行和串行,以及await底层实现
前提代码
var query = function (value) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(value)
}, value)
})
}
并行 方式一 1秒后输出1000,再过1秒输出2000,再过1秒输出3000
query(1000).then(v => {
console.log(v)
})
query(2000).then(v => {
console.log(v)
})
query(3000).then(v => {
console.log(v)
})
并行 方式二 三秒后输出 [1000, 2000, 3000]
Promise.all([query(1000),query(2000),query(3000)]).then(v=>{
console.log(v)
})
串行 方式一 输出为 1秒后输出1000,再过2秒输出2000,再过3秒输出3000
query(1000).then(v => {
console.log(v)
return query(2000)
}).then(v => {
console.log(v)
return query(3000)
}).then(v => {
console.log(v)
})
串行 方式二 输出为 1秒后输出1000,再过2秒输出2000,再过3秒输出3000
let itor = generator()
itor.next().value.then(value => {
itor.next(value).value.then(value => {
itor.next(value).value.then(value => {
itor.next(value)
})
})
})
await底层实现
const isPromise = function (v) {
if (v !== null && /^(object|function)$/i.test(typeof v)) {
let then;
try {
then = x.then
} catch (err) {
return false
}
if (typeof then === 'function') return true
}
return false
}
function AsyncFunction(generator, ...params) {
return new Promise((resolve, reject) => {
let itor = generator(...params);
const next = v => {
let {
value,
done
} = itor.next(v)
if (done) {
resolve(value)
return
}
if (!isPromise(value)) value = Promise.resolve(value)
value.then(v => {
next(v)
}).catch(reason => {
reject(reason)
itor.throw(reason)
})
}
next()
})
}
AsyncFunction(function* generator() {
let value;
y1 = yield query(1000)
console.log(y1)
y2 = yield query(2000)
console.log(y2)
y3 = yield query(3000)
console.log(y3)
return 'zanlan'
}).then(v => {
console.log('所有请求都成功', v)
}).catch(reason => {
console.log('某个请求失败', reason)
})
一般函数实现
/* 真实项目 基于async/awai可以直接实现*/
/* 我们上面基于promise + generator + AsyncFunction函数,实现的就是async/await处理机制 */
/* async/awai是promise + generator的语法糖 */
(async function () {
let value;
try {
value = await Promise.reject('xxx')
console.log('第一个请求成功', value)
} catch (err) {
console.log(err)
}
value = await query(2000)
console.log('第二个请求成功', value)
value = await query(3000)
console.log('第三个请求成功', value)
})()
generator原理
把一个函数当做普通函数执行,是否可以创造它这个类的一个实例?
jquery.fn() // 工厂设计模式 实现
function* fn() { // generator 实现 ,itor 是fn的实例对象 fn内部代码没有执行
console.log(this)
return 10
}
let itor = fn()
console.log(itor)
输出 window,在输出 { value:10 , done:true }
function* fn() {
console.log(this)
return 10
}
let itor = fn()
console.log(itor.next())
输出 如下
function* generator() {
console.log(1)
yield 2
console.log(3)
yield 4
console.log(5)
yield 6
console.log(7)
return 8
}
let itor = generator()
console.log(itor.next())
console.log(itor.next())
console.log(itor.next())
console.log(itor.next())
输出 如下
function* generator() {
console.log(1)
let y2 = yield 2
console.log(y2)
console.log(3)
let y4 = yield 4
console.log(y4)
console.log(5)
let y6 = yield 6
console.log(y6)
console.log(7)
return 8
}
let itor = generator()
console.log(itor.next('aa'))
console.log(itor.next('bb'))
console.log(itor.next('cc'))
console.log(itor.next('dd'))
输出如下
function* generator1() {
yield 2;
yield 3;
return 4
}
function* generator2() {
yield 1;
yield* generator1();
yield 5;
return 6;
}
let itor = generator2();
console.log(itor.next())
console.log(itor.next())
console.log(itor.next())
console.log(itor.next())
console.log(itor.next())
Iterator 源码
class Iterator {
constructor(assemble) {
let self = this;
self.assemble = assemble;
self.index = 0;
}
next() {
let self = this;
let assemble = self.assemble;
if (self.index > assemble.length - 1) {
return {
done: true,
value: undefined
}
}
return {
done: false,
value: assemble[self.index++]
}
}
}
一般应用
let itor = new Iterator([10, 20, 30, 40])
console.log(itor.next())
console.log(itor.next())
console.log(itor.next())
console.log(itor.next())
console.log(itor.next())
下面代码可以使得一般对象使用for of 循环
Object.prototype[Symbol.iterator] = function () {
let self = this
let keys = Object.keys(self).concat(Object.getOwnPropertySymbols(self))
let index = 0
return {
next() {
if (keys.length - 1 < index) {
return {
done: true,
value: undefined
}
}
return {
value: self[keys[index++]],
done: false
}
}
}
}
针对类数组,则直接借用真数组自带的Symbol.iterator函数
var obj = {
0: 'a',
1: 'b',
length: 2
}
obj[Symbol.iterator] = Array.prototype[Symbol.iterator]
for (var value of obj) {
console.log(value)
}
jquery是类数组,下面是jquery源码实现
jQuery.fn[Symbol.iterator] = [][Symbol.iterator];
async && await 面试题
已知两个函数,分别提问,得出结果
var f1 = function f1() {
console.log(1)
return new Promise(resolve => {
setTimeout(() => {
resolve(6)
console.log(5)
}, 2000);
})
}
var f2 = function f2() {
console.log(2)
return new Promise(resolve => {
setTimeout(() => {
resolve(4)
console.log(3)
}, 1000);
})
}
问题1 输出结果为 :1 5 6 2 3 4
var f = async function () {
console.log(await f1())
console.log(await f2())
}
f()
问题2 输出结果为 :1 2 3 5
Promise.all([
f1(),
f2(),
])
问题3 输出结果为 :1 2 3 4 5 6
Promise.all([
(async () => { console.log(await f1()) })(),
(async () => { console.log(await f2()) })(),
])