Proxy的实现

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 小黄   汪汪叫
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值