Proxy的实现

news/2024/7/9 3:18:28

1.Proxy的实现
(1)New创建的proxy(不可撤销)
var pro = new Proxy(person,{

        get:function(target,property){

        return 'ls'

        }

        set:function(target,property,value){

        return ''

        }

})

get方法:target参数表示所要拦截的目标对象,property表示属性

set方法:三个属性,target,property,value(属性值)

ownKeys:拦截操作,拦截过滤Object.keys()对对象的属性遍历

let person = {name:'老王',age:40,height:1.8}

let proxy = new Proxy(person,{

        ownKeys:function(target){

                return ['name','age']

        }

})

Object.keys(proxy);  //结果:[“name”,”age”]

ownKeys得到的只是被过滤后的结果:[“name”,”age”]。

has方法:拦截key in object的操作,结果会返回一个布尔值,has( )方法用于是判断是否含有指定的键值对,有,就返回true,否则返回false

(2)函数代理:apply调用


(3)proxy.revocable方法(可撤销的) 
Proxy.revocable( )(可废止的,可撤回的;)函数来实现,它会返回一个对象

有一个属性revoke,它是一个方法,用于取消代理。

        let obj = Proxy.revocable(person,{})

        obj.revoke();

Proxy.revocable( )方法返回的结果是一个对象

2.for...of使用
(1)for…of使用
        for...of 一种用于遍历数据结构的方法。它可遍历的对象包括数组,字符串,set和map结构等具有iterator 接口的数据结构。(不包含对象)

传统的遍历数组的方式以及它们的缺陷:

                1.for循环来遍历数组的缺点:代码不够简洁

                2.forEach循环代码量少了很多,写法更加简洁,缺点就是:无法中断停止整个循环。

                3. for...in循环更常用于对象的循环,如果用于数组的循环,那么就要注意了,上述代码中每次循环中得到的i是字符串类型,而不是预料中的数字类型,要想对它进行运算,那得先要进行类型转换,造成不方便。

for...of的优势:for(let value of arr){}

可以用break来终止整个循环,或者continute来跳出当前循环,继续后面的循环;

但直接获取的是值而不是索引。

       结合keys( )获取到循环的索引,并且是数字类型,而不是字符串类型。

        //得到数字类型索引

        var arr = [1,2,3,4,5]

        for(let index of arr.keys()){

                console.log(index);   //0,1,2,3,4

        }

        //得到 [值,索引]

        for(let [i,value] of arr.entries()){

                console.log([i,value]);  //[1,0]  [2,1] [3,2] [4,3] [5,4]

        }

        //遍历字符串

           let str = '我是前端'

            for (let s of str) {

                console.log(s);  //依次打印:我 是 前 端

            }

3.Iterator遍历器
(1)Object对象的原型上没有Symbol.iterator,所以for...of不能遍历对象(object)
(2)Iterator原理:原型上有[Symbol.iterator]方法,这个方法返回一个迭代器对象Iterator,这个对象有一个next属性,属性值又是一个函数,函数返回一个对象,对象有两个属性done表示完成状态,value是属性值
(3)自定义Iterator遍历器
    let obj = { 'age': 18, 'name': 'zs', 'height': 180 }

    obj[Symbol.iterator] = function () {

        let list = Object.keys(obj)

        let num = -1;

        return {

            next: function () {

                num++

                // let value=obj[list[num]]

                let value = {};

                value[list[num]] = obj[list[num]]

                let done = list.length === num

                return {

                    done,

                    value

                }

            }

        }

    }

    for (let value of obj) {

        console.log(value);    //{age:18}  {name:'zs'}  {height:180}

    }

4.Generator函数
(1)普通函数和Generator函数的区别
  普通函数用function来声明,Generator函数用function*声明。

        Generator函数函数内部有新的关键字:yield( 产出)暂停,下一次调用从当前位置继续执行,普通函数没有。

(2)调用Generator函数
 function* Hello(name) {

        yield `hello ${name}`;

        yield `How are you?`;

        yield `bye`;

    }

    let ite1 = Hello('前端君')

    console.log(ite1.next());  //{value: 'hello 前端君', done: false}

    console.log(ite1.next());  //{value: 'How are you?', done: false}

    console.log(ite1.next());  //{value: 'bye', done: false}

    console.log(ite1.next());  //{value: undefined, done: true}

(3)yield语句的使用
        yield在这里相当于暂停执行并且返回信息。有点像传统函数的return的作用,但不同的是普通函数只能return一次,但是Generator函数可以有很多个yield。

(4)next方法接收参数
next( )方法还可以接收一个参数,它的参数会作为上一个yield的返回值,

function* Hello() {

        let res = yield `hello`;

        yield res;

    }

    let iterator = Hello(); //结果:一个生成器对象

    console.log(iterator.next());  //结果:{value: "hello", done: false}

    console.log(iterator.next("前端君"));  //结果:{value: "前端君", done: false}

(5)关键字‘yield*’
        Generator函数里面,如果我们想调用另一个Generator函数,就需要用到的关键字是:yield*。

function* gen1() {

        yield "gen1 start";

        yield "gen1 end";

    }

    //声明Generator函数:gen2

    function* gen2() {

        yield "gen2 start";

        yield "gen2 end";

    }

    //声明Generator函数:start

    function* start() {

        yield "start";

        yield* gen1();

        yield* gen2();

        yield "end";

    }

    //调用start函数

    var ite = start();

    //创建一个生成器

    ite.next();   //{value: "start", done: false}

    ite.next();   //{value: "gen1 start", done: false}

    ite.next();   //{value: "gen1 end", done: false}

    ite.next();   //{value: "gen2 start", done: false}

    ite.next();   //{value: "gen2 end", done: false}

    ite.next();   //{value: "end", done: false}

          如果一个Generator函数A执行过程中,进入(调用)了另一个Generator函数B,那么会一直等到Generator函数B全部执行完毕后,才会返回Generator函数A继续执行。

(6)Generator函数的用途
        它可以控制函数的内部状态,依次遍历每个状态;可以根据需要,轻松地让函数暂停执行或者继续执行。

             根据这个特点,我们可以利用Generator函数来实现异步操作的效果。

5.类基本用法
         1.必须使用new关键字来创建类的实例对象

        2.先声明定义类,再创建实例,否则会报错

        类的静态方法:如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”

        类的继承,ES6使用extends关键字来实现子类继承父类

        用super来引用父类,访问父类的方法

在子类中调用父类的say方法的话,使用super.方法名( )即可实现。

  class Animal{

        constructor(name){

            this.name=name;

        }

        say(){

            console.log('This is a '+this.name);

        }

        static food(){

            console.log('喜欢吃什么?');

        }

    }

    //1.必须使用new关键字来创建类的实例对象

    // 2.先声明定义类,再创建实例,否则会报错

    let dog=new Animal('dog');

    console.log(dog.name);  //dog

    dog.say()         //This is a dog

    // 如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,

    // 而是直接通过类来调用,这就称为“静态方法”

    Animal.food();  //喜欢吃什么?

    // dog.food()   //报错:dog.food is not a function

    //类的继承,ES6使用extends关键字来实现

    class Dog extends Animal{

        constructor(name,color){

            //用super来引用父类,访问父类的方法

            super(name)

            this.color=color;

        }

        say(){

            super.say()

            console.log('汪汪叫');

        }

    }

    let myDog=new Dog('小黄','yellow')

    myDog.say();   //This is a 小黄   汪汪叫
 


http://lihuaxi.xjx100.cn/news/1170264.html

相关文章

删除Windows11和WIN10桌面图标小箭头

方法一: 1.右键“开始”菜单,找到“运行”,输入命令 regedit ,打开“注册表编辑器” 2.在“注册表编辑器”左侧窗口,按照以下路径找到对应项 HKEY_CLASSES_ROOT\lnkfile 3.选择右侧窗口的lsShortcut项,右击lsShortcut项,点击删除选项,将lsShortcut删除即可 4.重启电…

探索编程的极限:挑战炫技代码

程序员常常被视为具有超强技术能力的人才,而他们手中的代码也往往充满了令普通人惊叹的炫技操作。作为程序员的我,将和大家分享一些炫技的代码写法 一、编程语言介绍 本人主攻Java。下面我将介绍一下Java语言。 Java是一种广泛使用的高级编程语言&…

Tomcat源码:Acceptor与Poller、PollerEvent

参考资料: 《Tomcat源码解析系列(十一)ProtocolHandler》 《Tomcat源码解析系列(十二)NioEndpoint》 前文: 《Tomcat源码:启动类Bootstrap与Catalina的加载》 《Tomcat源码:容器…

运营-17.留存

如何定义留存 某段时间内的新增用户,经过一段时间后,又继续使用应用的被认作是留存 用户,这部分用户占当时新增用户的比例即是留存率,即用户没有流失; 例如: 5月份新增用户200,这200人在6月份启…

基础篇009.1 STM32驱动RC522 RFID模块之一:基础知识

目录 1. RFID概述 1.1 RFID工作原理 1.2 RFID分类 1.3 RFID模块 1.4 RFID卡片 1.5 IC卡和ID卡介绍 1.6 IC卡和ID的区分 2. Mifare卡结构原理 2.1 Mifare卡概述 2.2 Mifare非接触式 IC 卡性能简介(M1) 2.2.1 Mifare S50与Mifare S70 2.2.2 S5…

【通义千问】什么是通义千问,如何免费获得内测和使用方法。

什么是通义千问,如何免费获得内测和使用方法。 什么是通义千问怎么获得内测资格申请方法有两种第一种直接点击申请体验第二种直接点击使用邀请码 通义千问邀请码怎么获得参与社区活动邀请好友关注通义千问微信公众号参加通义千问线上课程向通义千问官方提问 通义千问…

超级简单的SSM框架(全注解,源码+分析,看一眼就会)

1.什么是SSM? SSM是Spring、SpringMVC、Mybatis的框架整合。 2.什么是Spring? Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。 优点: 1.通过Spring的IOC特性,将对象之间的…

建筑专业应届生零基础想学习数据分析,职业发展前景如何?能学会吗?

建筑应届生零基础想学习数据分析,职业发展前景如何?能学会吗? 当然是能学会的,但如果想要有发展前景,不仅是会数据分析而已,更需要实战能力,能够结合不同的业务进行分析,掌握各种常见…