Ada*_*dam 5 javascript proxy ecmascript-6
function createProxy() {
const myArray = [Math.random(), Math.random()];
return new Proxy(myArray, {});
}
const myProxy = createProxy();
Run Code Online (Sandbox Code Playgroud)
如何访问这里的target(是myArray)myProxy?
我尝试了很多方法。在Google上搜索了许多博客文章,但没有找到目标的方法:(
Cal*_*ner 71
如果您使用 Vue 3 并处理代理,Vue 提供了一些方法来帮助解决此问题:
import { isProxy, toRaw } from 'vue';
Run Code Online (Sandbox Code Playgroud)
使用这些,您可以检查对象是否是代理isProxy,例如:
isProxy(reactiveObjectOrArray) ? 'yup' : 'nope'
Run Code Online (Sandbox Code Playgroud)
您可以使用以下方法提取原始数据toRaw:
const rawObjectOrArray = toRaw(reactiveObjectOrArray)
Run Code Online (Sandbox Code Playgroud)
Ras*_*leh 23
您可以使用以下命令复制代理返回的数据Object.assign():
const target_copy = Object.assign({}, my_proxy);
Run Code Online (Sandbox Code Playgroud)
这将适用于代理/目标上存在的所有可枚举自己的属性。
小智 6
有一种巧妙的方法-您可以将get陷阱添加到代理,并让它有条件地返回目标。像这样
let resolveMode = false; // Switch that controls if getter returns target or prop.
function resolve(obj) {
resolveMode = true; // Turn on our switch
let target = obj.anything; // This gets the target not the prop!
resolveMode = false; // Turn off the switch for the getter to behave normally
return target; // Return what we got!
}
function createProxy() {
const myArray = [Math.random(), Math.random()];
return new Proxy(myArray, {
get: function(target, prop) {
if (resolveMode) return target; // This is where the magic happens!
else return target[prop]; // This is normal behavior..
}
});
}
const myProxy = createProxy();
let target = resolve(myProxy);
Run Code Online (Sandbox Code Playgroud)
请记住,添加到陷阱的代码行越多,对象的性能就越慢。希望这可以帮助。
就像已经说过的其他答案一样,代理获取陷阱可能是一个优雅的解决方案。
const IDENTITY = Symbol('proxy_target_identity')
const handler = {
get: (target, property, receiver) => {
if (property === IDENTITY) {
return target
}
return Reflect.get(target, property, receiver)
}
}
function createProxy() {
const myArray = [Math.random(), Math.random()];
return new Proxy(myArray, handler);
}
const myProxy = createProxy();
const orignal_target = myProxy[IDENTITY]
Run Code Online (Sandbox Code Playgroud)
此代码示例应该非常健壮,因为它:
SymbolReflect.get而不是覆盖所有获取场景target[property]not_itself_a_proxy[IDENTITY]调用将不会返回,not_itself_a_proxy而是原型的“身份”!其他答案给出了一些很好的解决方案。这是@Yuci 为类提炼出来的答案,在这种情况下,它就像定义一些特殊名称的实例变量一样简单。Proxy get 函数返回它,底层目标也是如此。
class Foo {
constructor() {
this.__target__ = this;
return new Proxy(this, {
get: function (target, name) {
if (name in target) return target[name];
// your code here
}
});
}
}
let foo = new Foo();
let target = foo.__target__;
console.log('proxied Foo', foo);
console.log('recovered target', target, target.__target__.__target__);
Run Code Online (Sandbox Code Playgroud)
我发现(使用 Vue.js 有时会涉及代理对象,例如在观看组件道具时)如果它是一个对象,如果它是一个数组,我可以使用以下方法获取目标JSON.stringify:
let myTarget = JSON.parse(JSON.stringify(myProxy))
Run Code Online (Sandbox Code Playgroud)
这种方法也适用于数组目标,而Object.assign({}, myProxy)仅适用于目标是对象。
但是我对 JavaScript 代理很陌生,而且我的知识有限。我可能不理解这种方法的局限性和注意事项。尽管如此,也许它可以帮助某人!
| 归档时间: |
|
| 查看次数: |
3515 次 |
| 最近记录: |