当前位置:   article > 正文

ES6-2:Iterator、Proxy、Promise、生成器函数...

ES6-2:Iterator、Proxy、Promise、生成器函数...

11-Iterator迭代器

在这里插入图片描述

  1. 打印出的是里面的内容,如果是for in打印出来的是索引,of不能遍历对象
  2. Symbol.iterator是js内置的,可以访问直接对象arr[Symbol.iterator],()调用
  3. 对象非线性一般不能迭代
    在这里插入图片描述
    在这里插入图片描述
    后两个是伪数组,但是是真迭代器接口
 ...解构赋值
 ...展开运算符默认会调用内置迭代器,自动转换为数组形式
  • 1
  • 2

12-set结构

  1. 类似于数组,但成员的值都是唯一的,没有重复
  2. 与数组不同的是set没有索引
 let s1=new Set([1,2,3,4,2,1])
        console.log(s1);
        console.log([...s1]);//...展开运算符默认会调用内置迭代器,自动转换为数组形式
        console.log(Array.from(s1));//将类似于数组的内容转化为真数组
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

 set结构键名和键值相同,放进一个数组[11 ,11][22,22][33,33]
        for(let i of s2.entries()){
            console.log(i);
        }
 set结构没有索引只有一个值,因此结果是11 11;22 22;33 33
        s2.forEach((item,index)=>{
            console.log(item,index);
        })
// 数组也可以用entries
        // let arr=["aa","bb","cc"]
        // for(let i of arr.entries()){
        //     console.log(i);//打印出来是索引和值组成的数组
        // }
        let arr=["aa","bb","cc"]
        for(let [index,item] of arr.entries()){
            console.log([index,item]);
        }//[0,11][1,22][2,33]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

面试题:给一个数组去重

思路:把数组里面的item都转换为字符串(因为set无法区分对象),再送到set里面进行判断有没有

arr. filter()方法里面的函数返回false会清除该数据,true会保留

let list=[1,2,2,"kerwin","kerwin",[1,2],[3,4],[1,2],
{name:"kerwin"},{age:100},{name:"kerwin"},undefined,undefined];
    function uni(arr){
        let res=new Set();
        return arr.filter(item=>{
            let id=JSON.stringify(item);
            if(res.has(id)){
                return false;
            }else{
                res.add(id);
                return true;
            }
        })
    }
    console.log(uni(list));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在这里插入图片描述

13-Map结构

类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
内置Iterator迭代器对象(用for of遍历比普通对象便利)
在这里插入图片描述
在这里插入图片描述

		let o={a:1}
        let m2=new Map();
        m2.set("name","kerwin");
        m2.set("age",100);
        m2.set(o,"大连");
        console.log(m2);
        for(let i of m2){
            console.log(i);
        }
        console.log([...m2]);//里面得到的是数组形式
        // set get has delete size clear
        console.log(m1.get({a:1}));//两个对象地址不一样,undefined拿不到m2里面的值
        console.log(m2.get(o));//大连

keys() values() entries() 返回的都是一个迭代器 用for of遍历,foreach
        for(let i of m1.values()){
            console.log(i);
        }
        for(let i of m1.entries()){
            console.log(i);
        }
        for(let [index,item] of m1.entries()){
            console.log([index,item]);
        }
        for(let [index,item] of m1){
            console.log([index,item]);
        }
        console.log("======");
        m1.forEach((item,index)=>{
            console.log(item,index);
        })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

14-Proxy代理

Proxy的作用是在对象和和对象的属性值之间设置一个代理,获取或设置该对象的值,以及实例化等多种操作,都会被拦截住,经过这一层我们可以统一处理,我们可以认为它就是”代理器”

			let s=new Set();
            // 只能修改代理proxy才能修改s
            // 代理拥有代理对象的所有东西
            let proxy=new Proxy(s,{
            // 方法内部用到了this,this应该指向实例化对象,但用了proxy代理后指向了proxy,
            // 因此报错需要修改this指向(也就是set里找自带方法才能去调用add()什么的)
                get(target,key){
                    let value=target[key]
                    // 判断value是不是一个方法(instanceof用于判断左边的对象是不是右边的类的实例)
                    if(value instanceof Function){
                        // 用于修正的方法:call apply bind前两个在修正的时候就手就调用了,而bind不会
                        // call() apply() bind()括号里填修正的指针指向谁
                        return value.bind(target);// target就是Set对象因此填写target
                    }
                    // get必须要返回东西
                    return value
                },
                set(target,key,value){
                    console.log("set",target,key,value);//{},name,"kerwin"
                        if(key=="date"){
                            box.innerHTML=value;
                        }
                    target[key]=value;
                }
            })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

proxy本质上属于元编程非破坏性数据劫持,在原对象基础上进行了功能的衍生而又不影响对象

15-Reflect

Reflect可以用于获取目标对象的行为,它与Object类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与Proxy是对应的。

1.代替object的某些方法

在这里插入图片描述

2.修改某些object的方法返回结果

在这里插入图片描述

3.命令式变为函数行为

在这里插入图片描述

get,set方法

let obj = {
                name:"kerwin"
            }
            Reflect.set(obj,"age",100)
            Reflect.get(obj,"name")
  • 1
  • 2
  • 3
  • 4
  • 5

4.配合proxy使用:

let s=new Set();
            let proxy=new Proxy(s,{
                get(target,key){
                    // let value=target[key]
                    let value=Reflect.get(target,key)
                    // 判断value是不是一个方法(instanceof用于判断左边的对象是不是右边的类的实例)
                    if(value instanceof Function){
                        // 用于修正的方法:call apply bind前两个在修正的时候就手就调用了,而bind不会
                        // call() apply() bind()括号里填修正的指针指向谁
                        return value.bind(target);// target就是Set对象因此填写target
                    }
                    // get必须要返回东西
                    return value
                },
                set(target,key,value){
                    // Reflect.set(target,key,value)
                    Reflect.set(...arguments)//如果是一个数组,用...展开传进去
                }
            })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

16-Promise对象

promise是异步编程的一种解决方案,比传统的解决方案回调函数更合理和更强大。
在这里插入图片描述

1.使用:

 // 执行器函数
        let pro=new Promise(function(resolve,reject){
            setTimeout(()=>{
                // resolve(1000)
                reject("no 1111")
            },1000)
        })
        // pro.then(()=>{
        //     // 成功
        //     console.log("奖金");
        // },()=>{
        //     // 失败
        //     console.log("没有");
        // })
        pro.then((res)=>{
                // 成功的函数
                console.log("奖金",res);
            }).catch((err)=>{
                // 失败的函数
                // 捕获错误
                console.log("没有",err);
            })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2.Promise对象的状态(

  • Promise对象通过自身的状态,来控制异步操作。Promise实例具有三种状态:
    异步操作未完成(pending)
    异步操作成功(fulfilled)
    异步操作失败(rejected)
  • 这三种的状态的变化途径只有两种。
    从“未完成”到“成功”
    从“未完成”到“失败”
  • 一旦状态发生变化,就不会再有新的状态变化。这也是Promise这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise实例的状态变化只可能发生一次
    因此,Promise的最终结果只有两种:
    异步操作成功,Promise实例传回一个值(value),状态变为fulfi1led。
    异步操作失败,Promise实例拋出一个错误(error),状态变为rejected。

在这里插入图片描述

3. .then.then链式调用

看第一个.then返回的结果,如果是非promise对象,会自动转换为fulfilled对象。
如果是,根据这个新的promise对象决定下一步是resolve执行then还是reject执行catch

在这里插入图片描述
在这里插入图片描述

4.promise方法:all,race

  1. Promise.all():里面的几个都成功了才走.then,只要有一个失败就走.catch
    ·[pro1,pro2,pro3]数组里面的一起执行
  2. Promise.race(),谁先回来就执行谁相应的状态指定的回调函数
    在这里插入图片描述
    应用场景:超时处理(pro1,pro2其中一个如果执行不了就返回超时)
    在这里插入图片描述

17-Generator生成器函数

返回值就是一个遍历器
在这里插入图片描述
yield表达式返回值取决于下一个next()方法中传入的参数

<script>
    // 协程让函数暂停执行,需要调用next()才能往下走
    function* gen() {
        console.log(11);
        yield "aa"; //中文产出的意思
        console.log(22);
        yield "bb";
        console.log(33);
        //如果是return "cc"不会被遍历出来,打印出来value是“cc”,done已经变成true了,是true时就停了
      }
      let g=gen()
    //   g.next()//11
    //   g.next()//22
    //   g.next()//33
    let res1=g.next()
    console.log(res1);
    let res2=g.next()
    console.log(res2);
    let res3=g.next()
    console.log(res3);
//for(let i of g){
        //    console.log(i);
        //}可以一下子遍历完
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在这里插入图片描述
在这里插入图片描述
结果不会有”-11111“(还没有给res1赋值就遇到yield停止了)

在这里插入图片描述

18-Class语法

1.类的写法

在这里插入图片描述
在这里插入图片描述

2.getter与setter拦截属性

不能在location里面拦截后再操作自己的属性,会进入一个死循环的递归调用

class Person{
            constructor(name,age,id){
                this.name=name;
                this.age=age;
                this.ele=document.querySelector(`#${id}`);
            }
            get location(){
                console.log("get");
            }
            set location(data){
                console.log("set",data);
            }
            get html(){
                return this.ele.innerHTML
            }
            set html(data){
                this.ele.innerHTML=data.map(item=>`<li>${item}</li>`).join("")
            }
        }

        let obj=new Person("kerwin",100,list)

        obj.html=["111","222","333"]
        // 在控制台赋值obj.html=["111","222","333"]时候会被set拦截到,它基于html把数据映射成li节点
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在这里插入图片描述

class Person{
            // 如果希望一个属性是静态的可以在前面加一个static
            static myname="person类的名字";
            static mymethod=function(){
                // console.log("mymethod",this.age);在这里访问不到age,因为this指向的是Person的类名,不是实例化对象
            }
            constructor(name,age,id){
                this.name=name;
                this.age=age;
            }
            say(){
                console.log(this.name,this.age);
            }
        }
        Person.myname="person类的名字"
        Person.mymethod=function(){
            console.log("mymethod");
        }
        let obj=new Person("kerwin",100)
        // 访问,在控制台obj.myname访问不到,
        //应用场景:有些属性或方法不需要实例化对象就可以挂在类的身上(称为静态属性和静态方法),比如person都会的事
        // console.log(Person.myname);
        // Person.mymethod()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

3.Class继承

1.super()方法继承调用父类constructor里面的方法
2.如果和父类方法名一样会就近原则执行,执行自己的覆盖父类,包括静态属性和静态方法
3.如果想在父级相同的方法基础上添加一些操作,需要调用super

class Student extends Person{
            constructor(name,age,score){
                super(name,age)
                this.score=score;
            }
2.如果和父类方法名一样会就近原则执行,执行自己的覆盖父类
            // say(){
            //     console.log(this.name,this.age,this.score);
            // }
3. 如果想在父级相同的方法基础上添加一些操作,需要调用super
            say(){
                super.say();//调用父级的say方法
                console.log(this.score);
            }
            getScore(){
                console.log(this.score);
            }
        }
        let obj=new Student("kerwin",100,150)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

案例:用面向对象的思路将数据传给box

<div class="box1">
        <h1></h1>
        <ul></ul>
    </div><div class="box2">
        <h1></h1>
        <img src="" alt="">
        <ul></ul>
    </div>
    <script>
        var data1={
            title:"体育",
            list:["体育1","体育2","体育3"]
        }
        var data2={
            title:"综艺",
            url:"https//................................",
            list:["综艺1","综艺2","综艺3"]
        }
        class CreatBox{
            // 获取节点和数据
            constructor(select,data){
                this.ele=document.querySelector(select)
                this.title=data.title;
                this.list=data.list;
                // 初始化完后立即执行渲染页面
                this.render()
            }
            render(){
                let oh1=this.ele.querySelector("h1")
                let oul=this.ele.querySelector("ul")
                oh1.innerHTML=this.title
                oul.innerHTML=this.list.map(item=>`<li>${item}</li>`).join("")

            }
        }
        class CreatImgBox extends CreatImgBox{
            constructor(select,data){
                super(select,data)
                this.imgUrl=data.url
                this.render()//再调用一遍(防止子类中的某些操作执行不到而出错)
            }
            render(){
                super.render()
                let oimg=this.ele.querySelector("img")
                oimg.src=this.imgUrl
            }
        }
        new CreatBox(".box1",data1)
        new CreatImgBox(".box2",data2)
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

19-Module模块化

好处:异步加载、 私密不漏、 重名不怕(不同js包下面方法名相同的)、依赖不乱

 defer,async异步加载 不会被script标签阻塞,会继续往下面走
<script src="20-Module.js" defer></script>一直等到全部渲染完后才去执行
<script src="20-Module.js" async></script>一旦下载完渲染引擎就会中断渲染
<script src="20-1.js" type="module"></script>这种方式引入js会访问不到里面的方法
  • 1
  • 2
  • 3
  • 4

私密不漏引用方法1:

在哪用在哪引
1.在js里导出方法

// const obj={
//     A1,
//     A2
// }
// export default obj
export default {
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.在script里导入js中的方法

<body>
    <script type="module">
           // 导入js中的方法,A1的名称可以改变,from后的链接必须加'./'
        import A1 from './20-1.js'
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

重名问题解决:

import obj1 from './20-1.js'
import obj2 from './20-1.js'
console.log(obj1.test(),obj2.test())//重名不怕
  • 1
  • 2
  • 3

导入写法2:

不加default,不能改名(这种写法区别于解构)

export {
	A1A2
}
import {A1A2} from './20-1.js'
  • 1
  • 2
  • 3
  • 4
  • 5

重名问题解决:as表示重命名后

import {A1,A2,test as testA} from './20-1.js'
import {test as testB} from './20-2.js'
如果想一起导
import * as obj1 from './20-1.js'
import * as obj2 from './20-2.js'
  • 1
  • 2
  • 3
  • 4
  • 5

导入写法3:直接在方法前加export
**写法4:**混合使用
在这里插入图片描述

20-NodeJS中的模块化

在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/430435
推荐阅读
相关标签
  

闽ICP备14008679号