avatar

目录
【前端19_JS】ES 6:Proxy 过滤器、遍历器接口、function_

过滤器 Proxy

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

  • 作用:拦截操作,类似过滤器、代理器
Javascript
1
2
//建立过滤器
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 ,输出如下
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
var obj = {
name :"霍金"
};
//建立 关于目标 obj 的 Proxy 过滤器
var proxy = new Proxy(obj,{
//首先这里什么都没干
});

//通过代理来访问obj中的name属性
console.log(proxy.name);
//霍金
//什么都没干的时候过滤器就是 target 本身
  • 有 get 方法,输出如下
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var obj = {
name :"霍金"
};
//建立 Proxy 过滤器
var proxy = new Proxy(obj,{
//当你在这里写了get的时候,就已经开始修改读取的方法了
//所有的读取都走get语句,现在语句里啥都没有,所以 proxy.name 是 undefined
get() {

}
});

//通过代理来访问obj中的name属性
console.log(proxy.name);
//undefined
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//建立过滤器
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

读对象,找不到抛出错误

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

Javascript
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
//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 为 啥类型的标签,并且可以为标签添加属性和内容

Javascript
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
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 就不被允许读写

Javascript
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

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
  • 修改操作就是赋值呗~,看看下面的例子叭
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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();


遍历器接口

遍历原理

就是下标下移

Javascript
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
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*

这玩意叫啥?

  • 这里新出了个关键词 yield ,类似一个暂停符,到底有啥用请看下面的例子,
  • 这个星号放在哪里都行!
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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}
文章作者: Lovely Ruby
文章链接: https://wangzhongqing.xyz/p/47759.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ruby の いえ
打赏
  • 微信
    微信
  • 支付寶
    支付寶

评论