Vue3 中提供 isProxy() 方法,检查一个对象是否是由 reactive()、readonly()、shallowReactive() 或 shallowReadonly() 创建的代理。
function isProxy(value: any): boolean
在 JavaScript 中,没有内置的方法直接判断一个对象是否是 Proxy 对象。Proxy 对象是通过 new Proxy(target, handler) 创建的,它没有暴露任何直接的标识符来判断对象是否为 Proxy。不过,可以采用一些间接的方法来检查对象是否可能是 Proxy:
使用特定的属性或行为:如果你有控制权,可以在创建 Proxy 时添加一些特殊属性或方法来标识它。例如:
const handler = { get(target, prop, receiver) { if (prop === '__isProxy') { return true; } return Reflect.get(target, prop, receiver); }};
const target = {};const proxy = new Proxy(target, handler);
console.log(proxy.__isProxy); // true
这种方式为 Proxy 对象添加一个特殊属性 __isProxy
,可以用来标识它。
或者使用 WeakMap 进行标记,将所有创建的 Proxy 存储在一个 WeakMap 中,以便在需要时检查。
const proxyCache = new WeakMap();
function createProxy(target) { const proxy = new Proxy(target, {}); proxyCache.set(proxy, true); return proxy;}
function isProxy(obj) { return proxyCache.has(obj);}
const target = {};const proxy = createProxy(target);
console.log(isProxy(target)); // 输出: falseconsole.log(isProxy(proxy)); // 输出: true
Vue 在创建响应式 Proxy 对象时,会在对象上设置一个不可枚举的特殊标记。用__v_raw 标记来实现的。这个标记用于标识对象是经过 Vue 的响应式系统处理的。
export function isProxy(value: any): boolean { return value ? !!value[ReactiveFlags.RAW] : false}
isProxy 函数的实现会检查对象是否具有这个特定的标记。如果对象有这个标记,则说明它是一个响应式 Proxy 对象。这就是原理。