当前位置:首页 » 《休闲阅读》 » 正文

【前端】ES6:Proxy代理和Reflect对象

20 人参与  2024年10月22日 16:00  分类 : 《休闲阅读》  评论

点击全文阅读


文章目录

1 Proxy代理1.1 get方法1.2 set方法1.3 has方法1.4 this问题 2 Reflect对象2.1 代替Object的某些方法2.2 修改某些Object方法返回结果2.3 命令式变为函数行为2.4 配合Proxy

1 Proxy代理

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

ES6之前:

let obj = {}// let arr = [1,2,3] // push pop// console.log(box)Object.defineProperty(obj, "data", { // obj--对象,data--属性get(){console.log("get")        return box.innerHTML},set(value){console.log("set",value)// 设置 dombox.innerHTML = value}})console.log(obj)

1.1 get方法

let target = {}let proxy = new Proxy(target, {    get(target, prop){        return target[prop]    }})

1.2 set方法

let target = {}let proxy = new Proxy(target, {    get(target, prop){        return target[prop]    },    set(target, prop, value){        if(prop === "data"){            box.innerHTML = value        }        target[prop] = value;    }})

1.3 has方法

has捕获器,拦截对象属性的in操作符的调用,当使用in操作符来检查一个属性是否存在于一个对象时,如果对象是个proxy,has捕获器就会被调用。

let target = {    _prop: "内部数据"}let proxy = new Proxy(target, {    get(target, prop) {        return target[prop]    },    set(target, prop, value) {        if (prop === "data") {            box.innerHTML = value        }        target[prop] = value;    },    has(target, key) {        if (key[0] === '_') {            return false;        }        return key in target;    }})

1.4 this问题

let target = new Set()const proxy = new Proxy(target, {    get(target, key) {        const value =  target[key]        // 遇到Function都手动绑定一下this        // 正常调用时,this指向proxy        // bind修正后,value方法的this指向target对象        if(value instanceof Function) {            console.log(`访问${value}方法了`)            return value.bind(target)            // 不能是call / apply,改变页面加载之后就立即执行,同步代码            // bind 不会立即执行原函数,异步代码         }        return value    }})proxy.add(1)

Proxy本质上属于元编程非破坏性数据劫持,在原对象的基础上进行了功能的衍生而又不影响原对象,符合松耦合高内聚的设计理念。

2 Reflect对象

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

2.1 代替Object的某些方法

const obj = {};Reflect.defineProperty(obj, 'name', {    value: 'kerwin',    writable: false,    configurable:false});

2.2 修改某些Object方法返回结果

// 老写法try {  Object.defineProperty(target, property, attributes);  // success} catch (e) {  // fail}// 新写法if(Reflect.defineProperty(target, property, attributes)) {  // success} else {  // fail}

2.3 命令式变为函数行为

const obj = {    name:"kerwin"};//老写法console.log("name" in obj) //true//新写法console.log(Reflect.has(obj, 'name')) //true//老写法delete obj.name//新写法Reflect.deleteProperty(obj, "name")

2.4 配合Proxy

Reflect.set()和Reflect.get()。

let obj = {name:"kerwin"}Reflect.set(obj, "age", 100)console.log(Reflect.get(obj, "name"))
let target = new Set()const proxy = new Proxy(target, {    get(target, key) {        const value = Reflect.get(target, key)        if (value instanceof Function) {            console.log(`访问${value}方法了`)            return value.bind(target)        }        return value    },    set() { // set(target, key, value)        return Reflect.set(...arguments)    }})proxy.add(1)
let arr = [1, 2, 3]let proxy = new Proxy(arr, {    get(target, key) {        console.log('get', key)        return Reflect.get(...arguments)    },    set(target, key, value) {        console.log('set', key, value)        return Reflect.set(...arguments)    }})proxy.push(4)// 能够打印出很多内容// get push     (寻找 proxy.push 方法)// get length   (获取当前的 length)// set 3 4      (设置 proxy[3] = 4)// set length 4 (设置 proxy.length = 4)

点击全文阅读


本文链接:http://zhangshiyu.com/post/175579.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1