【前端19_JS】ES 6:Proxy 过滤器、遍历器接口、function*、类Class、Promise


ES6

过滤器 Proxy

修改某些操作的默认行为,比方说a标签的跳转
又叫元编程

  • 作用:拦截操作,类似过滤器、代理器
	//建立过滤器
	var proxy = new Proxy(target,handler);

它有两个属性,分别是 target 目标, handler 处理方法

target

就是过滤器的目标

目标是什么类型的,那么过滤器就是什么类型的

handler

他是过滤器的处理方法,就是要告诉过滤器,你咋过滤的?
它本身是个对象

以下是 handler 中的几个方法

get:改变“读取”操作

你的所有获取属性的方法都叫 读取 方法

  • 比方说 arr[0],这是用 中括号 来读取 arr 中下标为零的元素
  • console.log() 点方法 获取 console 对象中的 log 方法
  • get 有 三个参数,分别是
    target 目标,比方说 obj.name,目标就是 obj
    key 就是你点之后的东西,比方说 obj.namekey 就是 name
    第三个不咋用

而过滤器中的 get 会改变你读取 target 的方法

  • 没有 get ,输出如下
	var obj = {
        name :"霍金"
    };
    //建立 关于目标 obj 的 Proxy 过滤器
    var proxy = new Proxy(obj,{
        //首先这里什么都没干
    });
    
    //通过代理来访问obj中的name属性
    console.log(proxy.name);
    //霍金
    //什么都没干的时候过滤器就是 target 本身
  • 有 get 方法,输出如下
	var obj = {
        name :"霍金"
    };
    //建立 Proxy 过滤器
    var proxy = new Proxy(obj,{
        //当你在这里写了get的时候,就已经开始修改读取的方法了
        //所有的读取都走get语句,现在语句里啥都没有,所以 proxy.name 是 undefined
        get() {

        }
    });

    //通过代理来访问obj中的name属性
    console.log(proxy.name);
    //undefined
	//建立过滤器
    var proxy = new Proxy({name:"name的val"},{
        //get 封掉了读方法
        get(target,key){
            console.log("我拦截了读取操作");
            if (key == "prototype") {
                throw new Error("dont touch me");
            }
            return target[key];
        },
    });
    //你的所有点方法啊,[]什么的都是get方法
    console.log(proxy.name);
    //我拦截了读取操作
    //name的val
    
    console.log(proxy.prototype);
    //Uncaught Error: dont touch me
读对象,找不到抛出错误
	function Person() {
        this.name = "xiaopang"
    }
    var person1 = new Person();
    var handler = {
        get(target,key){
            if(key in target){
                return target[key];
            }else{
                throw new Error(`Cant find ${key} in ${target}`);
            }
        }
    };
    var proxy = new Proxy(person1,handler);
    console.log(proxy.name);
    //xiaopang

    console.log(proxy.age);
    //Uncaught Error: Cant find age in [object Object]
数组填负的下标,倒着找元素

问题描述:
有个数组 array = [0,1,2,3,4,5,6,7]
我 console.log(array[-1]),就输出 7

	//rest参数,首先把传来的1,2,3,4,5,6,7压缩成数组,保存在rest中
    function searchF(...rest) {
        //写处理方法
        let handle = {
            //修改 get 读取方法
            get(tar,key){
                //把要找的负数的下标变成数
                //因为 key 是字符串,需要转换成数字
                let index = Number(key);
                if(key < 0){
                    //如果下标小于零,那么就跟着我游戏规则完
                    key = tar.length + index;
                }
                //返回找到的元素,给 get 方法
                return tar[key];
            }
        };
        //这个 searchF 返回个过滤器
        return new Proxy(rest,handle)
    }
    //这时候的 array 已经是过滤器了
    var array = searchF(0,1,2,3,4,5,6,7);

    //读取,走get方法
    console.log(array[-1]);
    //7
创建 key 类型的标签

问题描述:
通过过滤器在页面中添加节点,key 为 啥类型的标签,并且可以为标签添加属性和内容

const creatDom = new Proxy({},{
        get(target,key) {
            //这里的attrs承接创建标签的属性,other是标签的其他数据
            return function (attrs = {},...other) {

                //创建游离标签元素,key值是你想要创建啥标签
                // 比方说 creatDom.a,key 就是 a
                let ele = document.createElement(key);

                //循环设置标签属性
                for (let x of Object.keys(attrs)) {
                    ele.setAttribute(x,attrs[x]);
                }

                //这里用forin是不对的,forin 是取key的,这里的话就是下标了
                for (let oth of other) {
                    if(typeof oth === "string"){
                        //创建文本节点
                        oth = document.createTextNode(oth);
                    }
                    ele.appendChild(oth);
                }
                return ele;
            }
        }
    });
    
    //a1承接过滤器返回的ele游离节点
    var a1 = creatDom.a({href:"123.html"},"文本1","我是个文本2");
    
    //把节点插入到body中
    document.body.appendChild(a1);
    
    //others 中可以接着往下写下一级的东西,比方说如下
    var a2 = creatDom.div({},creatDom.ul({},creatDom.li({},"这是第一个")));
    document.body.appendChild(a2);

在这里插入图片描述

不允许读取私有属性

要求描述:
不允许读写对象属性中以 _ 下划线打头的属性
比方说
const obj = {_pro:1}; 中的 _pro 就不被允许读写


	const people = {
        name:"Wangbaoqiang",
        _nickname:"高冷男神"
    };
    function check(key,method) {
    	//如果它前面有下划线,代表咱要处理它,不让外面的人来读写!
        if(key[0] == "_"){
            throw new Error(`${method} is not use _`);
        }
    }
    const handler = {
        get(tar,key){
            check(key,"get");
            return tar[key];
        },
        set(tar, key, val) {
            check(key,"set");
            tar[key] = val;
        }
    };
    //设置过滤器
    const proxy = new Proxy(people,handler);

    console.log(proxy);
    //Proxy {name: "Wangbaoqiang", _nickname: "高冷男神"}
    
    //读取普通属性,No problem
    console.log(proxy.name);
    //Wangbaoqiang

    //尝试读取私有属性_nickname
    console.log(proxy._nickname);
    //Uncaught Error: get is not use _

    //尝试改写私有属性_nickname,死心吧~
    proxy._nickname = "我就要改!!改不动md";
    //Uncaught Error: set is not use _
set :改变“修改”操作
  • set 和 get 很相似,set 多了一个参数 value
  • 修改操作就是赋值呗~,看看下面的例子叭
	const people = {
        name:"xiaopang"
    };

    var proxy = new Proxy(people,{
    	//receiver 这参数蛮闲鱼的,有兴趣自己试试吧
        set(target, key, value, receiver) {
            if (key == "age") {
                if (value < 18) {
                    console.log(`${key}太小了,送你一箱练习册`);
                    return;
                }
            }
            //set就不用返回值了,你直接设置就可以了
            target[key] = value;
        }
    });
    //这里你开始了改写操作,所以走代理器中的set方法
    proxy.age = 17;
    //age太小了,送你一箱练习册

    proxy.habit = ["sing","sang"];
    console.log(people);
    {name: "xiaopang", habit: Array(2)}
apply

我需要研究一下

ownKeys :封掉关键字的使用

我需要研究一下

Proxy.revocable();


遍历器接口

遍历原理

就是下标下移

	function traversing(array) {
        //游标
        let index = 0;
        return {
            next:function () {
                //三目运算符
                return index < array.length ?
                    {val:array[index++],able:true}:
                    {val:undefined,able:false};
            }
        }
    }
    var arr = traversing([1,2,3,4]);
    console.log(arr.next());
    //{val: 1, able: true}

    console.log(arr.next());
    //{val: 2, able: true}

    console.log(arr.next());
    //{val: 3, able: true}

    console.log(arr.next());
    //{val: 4, able: true}

    console.log(arr.next());
    //{val: undefined, able: false}

function*

这玩意叫啥?
function* 这种声明方式(function关键字后跟一个星号)会定义一个生成器函数 (generator function),它返回一个 Generator 对象。

  • 这里新出了个关键词 yield ,类似一个暂停符,到底有啥用请看下面的例子,
  • 这个星号放在哪里都行!
	function* test() {
        yield "我是第一句";
        //yield相当于暂停符号,一步一步的执行,要用 next 手动执行这个玩意儿

        yield "我是第二句";
        return "yes";
    }
    var t = test();

    console.log(t);
    //test {<suspended>}

    console.log(t.next());
    //{value: "我是第一句", done: false}

    console.log(t.next());
    //{value: "我是第二句", done: false}

    //跟指针一样一直下移
    console.log(t.next());
    //{value: "yes", done: true}

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

类 Class

  • ES6 中迎来了真正的Class

  • ECMAScript 2015 中引入的 JavaScript 类实质上是 JavaScript 现有的基于原型的继承的语法糖。类语法不会为JavaScript引入新的面向对象的继承模型。MDN官方解释。

  • 定义类用如下的方法:

class Person{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    show(){
        console.log(`我叫${this.name},今年${this.age}岁`);
    }
}
var p1 = new Person("张三", 18)
p1.show()
  • 类方法是加在原型上的。

Promise

  • 他是一个对象,代表异步操作最终完成或失败
  • 解决回调地狱的问题
  • 时序:then中的函数被放到了微任务队列,而不是立即执行,等事件队列被清空之后再继续执行。
  • 类方法:Promise.all()Promise.race(),里面承接的是Promise数组
let promise = new Promise((resolve, reject) => {
    if (1) {
        resolve('操作成功');
    } else {
        reject('操作异常');
    }
});

function requestA() {
    console.log('请求A成功');
    return 'A请求的结果';
}
function requestB(res) {
    // 通过res来获得上一个返回来的结果
    console.log('上一步的结果:' + res);
    console.log('请求B成功');
    return 'B请求的结果';
}
function requestC(res) {
    console.log('上一步的结果:' + res);
    console.log('请求C成功');
}
function requestError() {
    console.log('请求失败');
}

//then处理操作成功,catch处理操作异常
promise.then(requestA)
    .then(requestB)
    .then(requestC)
    .catch(requestError);
// 请求A成功
// 上一步的结果:A请求的结果
// 请求B成功
// 上一步的结果:B请求的结果
// 请求C成功
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值