我们总是在各种前端面试题中发现Proxy,那么这个Proxy到底是什么呢?今天带你一篇文章吃透Proxy。
Proxy概述
Proxy对象用于创建一个对象的代理,从而实现基本操作和拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
术语
- handler
包含捕捉器(trap)的占位符对象,可译为处理器对象。
- traps
提供属性访问的方法。这类似于操作系统中捕获器的概念。
- target
被Proxy代理虚拟化的对象。它常被作为代理的存储后端。根据目标验证关于对象不可扩展性或不可配置属性的
不变量(保持不变的语义)。
语法
const p = new Proxy(target, handler);
参数
- target
要使用Proxy包装的目标对象(可以是任何类型大的对象,包括原生数组,函数,甚至另一个代理)。
- handler
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理p的行为。
方法
Proxy.revocable()
创建一个可撤销的Proxy的对象。
handler对象的方法
handler对象是一个容纳一批特定属性的占位符对象。它包含有Proxy的各个捕获器(trap)。
所有的捕捉器是可选的。如果没有定义某个捕捉器,那么就会保留源对象的默认行为。
handler.getPrototypeOf()
Object.getPrototypeOf()方法的捕捉器。
用途:是一个代理(Proxy)方法,当读取代理对象的原型时,该方法就会被调用。
基本用法:
var obj = {
};
var proto = {
};
var handler = {
getPrototypeOf(target) {
console.log(target === obj); // true
console.log(this === handler); // true
return proto;
}
};
var p = new Proxy(obj, handler);
console.log(Object.getPrototypeOf(p) === proto); // true
handler.setPrototypeOf()
Object.setPrototypeOf()方法的捕捉器。
用途:设置一个指定的对象的原型 (即, 内部[[Prototype]]属性)到另一个对象或 null。
基本用法:
var handlerThrows = {
setPrototypeOf(target, newProto) {
throw new Error('custom error');
}
}
var newProto = {
}, target = {
};
var p1 = new Proxy(target, handlerThrows);
Object.setPrototypeOf(p1, newProto); // throws new Error("custom error")
Reflect.setPrototypeOf(p1, newProto); // throws new Error("custom error")
handler.isExtensible()
Object.isExtensible()方法的捕捉器。
用途:判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。
基本用法:
var p = new Proxy({
}, {
isExtensible: function(target) {
console.log('called');
return true;//也可以return 1;等表示为true的值
}
});
console.log(Object.isExtensible(p)); // "called"
// true
handler.preventExtensions()
Object.preventExtensions()方法的捕捉器。
用途:让一个对象变的不可扩展,也就是永远不能再添加新的属性。
基本用法:
var p = new Proxy({
}, {
preventExtensions: function(target) {
console.log('called');
Object.preventExtensions(target);
return true;
}
});
console.log(Object.preventExtensions(p)); // "called"
// false
handler.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor()方法的捕捉器。
用途:返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
基本用法:
var p = new Proxy({
a: 20}, {
getOwnPropertyDescriptor: function(target, prop) {
console.log('called: ' + prop);
return {
configurable: true, enumerable: true, value: 10 };
}
});
console.log(Object.getOwnPropertyDescriptor(p, 'a').value); // "called: a"
// 10
handler.defineProperty()
Object.defineProperty方法的捕捉器。
用途:会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
基本用法: