当前位置: 首页 > article >正文

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

文章目录

  • 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)
		// 设置 dom
		box.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://www.kler.cn/a/319679.html

相关文章:

  • 【Qt聊天室客户端】消息功能--发布程序
  • 【学习日记】notebook添加JAVA支持
  • 探索 Python HTTP 的瑞士军刀:Requests 库
  • 有了Makefile, CMake存在的意义是什么?如何借助Makefile构建ObjC语言编译环境?如何获取编译器的版本号?
  • MySQL —— MySQL逻辑架构与查询过程
  • 【excel】easy excel如何导出动态列
  • 【百日算法计划】:每日一题,见证成长(020)
  • 如何查看线程
  • 项目第一弹:RabbitMQ介绍
  • C语言之预处理详解(完结撒花)
  • JAVA链表
  • 网站在线客服插件配置
  • Stable Diffusion的高分辨率修复(Hires.fix)
  • 嵌入式单片机中can总线调试方法
  • 漏洞扫描工具使用
  • vulnhub(11):derpnstink(hydra爆破用户名和密码、验证的文件上传)
  • 多表查询。
  • 以太坊客户端Geth的介绍与搭建
  • (PySpark)RDD实验实战——取一个数组的中间值
  • 求一个数的因子数(c语言)
  • C语言 | Leetcode C语言题解之第416题分割等和子集
  • 自然场景文本定位系统源码分享
  • MFC -文件类控件
  • 暑期内卷!就练这400页软件测试面试题(附答案解析)!
  • fmql之ubuntu添加dhcp服务
  • 函数题 7-7 12-24小时制【PAT】