Javascript 如何测试对象是否为代理?
我想测试一个JavaScript对象是否是一个。琐碎的方法Javascript 如何测试对象是否为代理?,javascript,ecmascript-6,proxy-classes,Javascript,Ecmascript 6,Proxy Classes,我想测试一个JavaScript对象是否是一个。琐碎的方法 if (obj instanceof Proxy) ... 在这里不起作用,遍历Proxy.prototype的原型链也不起作用,因为所有相关操作都由底层目标有效支持 是否可以测试任意对象是否为代理?来自: 无法确定对象是否为代理(透明虚拟化) 发件人: 无法确定对象是否为代理(透明虚拟化) 代理对象有两种方法。一个是新代理,另一个是代理。可撤销。我们可以监视它们,以便将代理对象记录到一个秘密列表中。然后,我们通过检查 它存在于秘密列
if (obj instanceof Proxy) ...
在这里不起作用,遍历Proxy.prototype
的原型链也不起作用,因为所有相关操作都由底层目标有效支持
是否可以测试任意对象是否为代理?来自:
无法确定对象是否为代理(透明虚拟化)
发件人:
无法确定对象是否为代理(透明虚拟化)
代理对象有两种方法。一个是
新代理
,另一个是代理。可撤销
。我们可以监视它们,以便将代理对象记录到一个秘密列表中。然后,我们通过检查
它存在于秘密列表中
为了监视函数,我们可以编写包装器或使用内置代理。后者意味着使用Proxy来代理新的Proxy
以及Proxy.recovable
,下面是一个示例
为了服务于类似的nodejs-v5.8.0代理,我们可以使用
Proxy.createFunction
将相同的思想应用于代理Proxy.create
和Proxy.createFunction
代理对象有两种方法。一个是新代理
,另一个是代理。可撤销
。我们可以监视它们,以便将代理对象记录到一个秘密列表中。然后,我们通过检查
它存在于秘密列表中
为了监视函数,我们可以编写包装器或使用内置代理。后者意味着使用Proxy来代理新的Proxy
以及Proxy.recovable
,下面是一个示例
为了服务于类似的nodejs-v5.8.0代理,我们可以使用
Proxy.createFunction
将相同的思想应用于代理Proxy.create
和Proxy.createFunction
在我当前的项目中,我还需要一种方法来定义某个东西是否已经是代理,主要是因为我不想在代理上启动代理。为此,我只向我的处理程序添加了一个getter,如果请求的变量是“\uuuproxy”,则返回true:
功能_观察(obj){
如果(对象_uuisproxy==未定义){
var ret=新代理(obj | |{}{
设置:(目标、键、值)=>{
///根据变化采取行动
返回true;
},
get:(目标,关键点)=>{
如果(键!==“\uu isProxy”){
返回目标[键];
}
返回true;
}
});
返回ret;
}
返回obj;
}
在我当前的项目中,我还需要一种方法来定义某个东西是否已经是代理,主要是因为我不想在代理上启动代理。为此,我只向我的处理程序添加了一个getter,如果请求的变量是“\uuuproxy”,则返回true:
功能_观察(obj){
如果(对象_uuisproxy==未定义){
var ret=新代理(obj | |{}{
设置:(目标、键、值)=>{
///根据变化采取行动
返回true;
},
get:(目标,关键点)=>{
如果(键!==“\uu isProxy”){
返回目标[键];
}
返回true;
}
});
返回ret;
}
返回obj;
}
似乎没有标准方法,但对于Firefox特权代码,您可以使用
Components.utils.isProxy(object);
例如:
Components.utils.isProxy([]); // false
Components.utils.isProxy(new Proxy([], {})); // true
const target = {};
const proxy = new Proxy(target, {});
util.types.isProxy(target); // Returns false
util.types.isProxy(proxy); // Returns true
似乎没有标准的方法,但对于Firefox特权代码,您可以使用
Components.utils.isProxy(object);
例如:
Components.utils.isProxy([]); // false
Components.utils.isProxy(new Proxy([], {})); // true
const target = {};
const proxy = new Proxy(target, {});
util.types.isProxy(target); // Returns false
util.types.isProxy(proxy); // Returns true
我发现最好的方法是创建一组弱代理对象。在构建和检查代理对象时,可以递归地执行此操作
var myProxySet = new WeakSet();
var myObj = new Proxy({},myValidator);
myProxySet.add(myObj);
if(myProxySet.has(myObj)) {
// Working with a proxy object.
}
我发现最好的方法是创建一组弱代理对象。在构建和检查代理对象时,可以递归地执行此操作
var myProxySet = new WeakSet();
var myObj = new Proxy({},myValidator);
myProxySet.add(myObj);
if(myProxySet.has(myObj)) {
// Working with a proxy object.
}
事实上,确定对象是否为代理存在一种变通方法,它基于几个假设。首先,通过C++扩展或浏览器中的特权网页,当页面可以启动不安全的扩展时,可以方便地解决代理代码确定问题。其次,代理是相对较新的功能,所以它不存在于旧的浏览器中-所以解决方案只适用于现代浏览器 JS引擎无法克隆函数(因为它们绑定到激活上下文和其他一些原因),但根据定义,代理对象由包装处理程序组成。所以,要确定对象是否是代理,启动强制对象克隆就足够了。可以通过函数来完成
若对象是代理,即使它不包含任何函数,也将无法复制。例如,Edge和Chrome在尝试发布代理对象时产生以下错误:
[object DomeException]:{code:25,消息:“DataCloneError”,名称:“DataCloneError”}
和未能在“窗口”上执行“postMessage”:[object object object]无法克隆。
事实上,确定对象是否为代理存在一种变通方法,它基于几个假设。首先,通过C++扩展或浏览器中的特权网页,当页面可以启动不安全的扩展时,可以方便地解决代理代码确定问题。其次,代理是相对较新的功能,所以它不存在于旧的浏览器中-所以解决方案只适用于现代浏览器
JS引擎无法克隆函数(因为它们绑定到激活上下文和其他一些原因),但根据定义,代理对象由包装处理程序组成。所以,要确定对象是否是代理,启动强制对象克隆就足够了。可以通过函数来完成
若对象是代理,即使它不包含任何函数,也将无法复制。例如,Edge和Chrome在尝试发布代理对象时产生以下错误:[object DomeException]:{code:25,消息:“DataCloneError”,名称:“DataCloneError”}
和未能在“窗口”上执行“postMessage”:[object object object]无法克隆。
在Node.js 10中,您可以
const proxy_set = new WeakSet()
window.Proxy = new Proxy(Proxy,{
construct(target, args) {
const proxy = new target(...args)
proxy_set.add(proxy)
return proxy
}
})
const a = external_script()
console.log(proxy_set.has(a)) //true
const is_proxy = Symbol('is_proxy')
const old_Proxy = Proxy
const handler = {
has (target, key) {
return (is_proxy === key) || (key in target)
}
}
window.Proxy = new Proxy(Proxy,{
construct(target, args) {
return new old_Proxy(new target(...args), handler)
}
})
const a = external_script()
console.log(is_proxy in a) //true
function getProxy(target, property) {
if (property === Symbol.for("__isProxy")) return true;
if (property === Symbol.for("__target")) return target;
return target[property];
}
function setProxy(target, property, value) {
if (property === Symbol.for("__isProxy")) throw new Error("You cannot set the value of '__isProxy'");
if (property === Symbol.for("__target")) throw new Error("You cannot set the value of '__target'");
if (target[property !== value]) target[property] = value;
return true;
}
function isProxy(proxy) {
return proxy == null ? false : !!proxy[Symbol.for("__isProxy")];
}
function getTarget(proxy) {
return isProxy(proxy) ? proxy[Symbol.for("__target")] : proxy;
}
function updateProxy(values, property) {
values[property] = new Proxy(getTarget(values[property]), {
set: setProxy,
get: getProxy
});
}
function shouldBeCloneable(o) {
const type = typeof o;
return (
type === "undefined" ||
o === null ||
type === "boolean" ||
type === "number" ||
type === "string" ||
o instanceof Date ||
o instanceof RegExp ||
o instanceof Blob ||
o instanceof File ||
o instanceof FileList ||
o instanceof ArrayBuffer ||
o instanceof ImageData ||
o instanceof ImageBitmap ||
o instanceof Array ||
o instanceof Map ||
o instanceof Set
);
}
function isCloneable(obj) {
try {
postMessage(obj, "*");
} catch (error) {
if (error?.code === 25) return false; // DATA_CLONE_ERR
}
return true;
}
function isProxy(obj){
const _shouldBeCloneable = shouldBeCloneable(obj);
const _isCloneable = isCloneable(obj);
if(_isCloneable) return false;
if(!_shouldBeCloneable) return "maybe";
return _shouldBeCloneable && !_isCloneable;
}
console.log("proxied {}", isProxy(new Proxy({},{})));
console.log("{}", isProxy({}));
console.log("proxied []", isProxy(new Proxy([],{})));
console.log("[]", isProxy([]));
console.log("proxied function", isProxy(new Proxy(()=>{},{})));
console.log("function", isProxy(()=>{}));
console.log("proxied Map", isProxy(new Proxy(new Map(),{})));
console.log("new Map()", isProxy(new Map()));
class A{};
console.log("proxied class", isProxy(new Proxy(A,{})));
console.log("class", isProxy(A));
console.log("proxied class instance", isProxy(new Proxy(new A(),{})));
console.log("class instance", isProxy(new A()));