es6总结

161 阅读4分钟

es6阮一峰

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()) })(),
    ])