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

news/2024/9/22 17:23:05 标签: 前端, es6, javascript

文章目录

  • 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之前:

javascript">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()。

javascript">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.niftyadmin.cn/n/5670654.html

相关文章

制造业的智能化革命:工业物联网(IIoT)的优势、层级应用及挑战解析

在全球制造业的蓬勃发展中,工业物联网(IIoT)作为一股颠覆性力量,正逐步重塑传统制造业的面貌。IIoT技术通过无缝连接设备、系统与人员,促进了数据的即时流通与处理,不仅极大地提升了制造效率,还…

Linux常见查看文件命令

目录 一、cat 1.1. 查看文件内容 1.2. 创建文件 1.3. 追加内容到文件 1.4. 连接文件 1.5. 显示多个文件的内容 1.6. 使用管道 1.7. 查看文件的最后几行 1.8. 使用 -n 选项显示行号 1.9. 使用 -b 选项仅显示非空行的行号 二、tac 三、less 四、more 五、head 六、…

Go语言并发编程中的超时与取消机制解析

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 并发编程是Go语言的核心优势之一,而在实际应用中,超时和取消操作会频繁出现。超时机制能够帮助我们理解系统行为,防止系统因为某些任务执行过长而陷入困境。与此同时,取消操作则是应对超时的一种自然反应。此…

机器学习 and 深度学习

机器学习(Machine Learning, ML)和深度学习(Deep Learning, DL)是人工智能领域中的两个重要分支,它们之间存在一定的联系与区别。 机器学习 机器学习是指让计算机通过数据来“学习”如何完成特定任务的技术。它依赖于…

消息中间件---Kafka

一、什么是Kafka? Kafka是一个分布式流处理平台,类似于消息队列或企业消息传递系统; 流处理事什么呢? 流处理就是数据处理工作流,本质上是一种计算机编程范例。流处理是对接收到的新数据事件的连续处理。‌它涉及对从生产者到消…

如何将很多个pdf拼接在一起?很多种PDF拼接的方法

如何将很多个pdf拼接在一起?将多个PDF文件合并不仅能够提升信息的整合性,还能使文件管理更加高效。想象一下,你需要向同事或老师提交一份综合报告,其中包含了多份相关资料。如果每个文件单独存在,查找和传输都会变得繁…

通信工程学习:什么是NFV网络功能虚拟化

NFV:网络功能虚拟化 NFV(Network Function Virtualization),即网络功能虚拟化,是一种通过虚拟化技术实现网络功能的技术手段。它借鉴了x86服务器的架构,将传统的网络硬件设备如路由器、交换机、防火墙、负载…

将sqlite3移植到开发板上

1、下载c源码 sqlite官网下载C源码:SQLite Download Page 点击第二个链接下载 2、解压 1、将下载好的c源码,放在linux下, 2、解压压缩包:tar -zxvf sqlite-autoconf-3460100 新建一个用存放 编译出来的文件: mkd…