gpt4 book ai didi

javascript - 在普通 JS 对象上同时使用 `get` 和 `apply` 代理陷阱

转载 作者:行者123 更新时间:2023-11-29 15:23:08 24 4
gpt4 key购买 nike

以下代码是一个简单的代理,用于记录被捕获的“gets”:

var p = new Proxy({}, {
get: function(target, property, receiver) {
console.log("getting: ", property);
return target[property];
}
});

当我使用 "hello "+ p 将其强制转换为字符串时,我在控制台中得到以下输出:

getting:  Symbol(Symbol.toPrimitive)
getting: valueOf
getting: toString
getting: Symbol(Symbol.toStringTag)
"hello [object Object]"

到目前为止一切都很好,但让我们做一些偷偷摸摸的事情并代理一个函数,但实际上仍然将它用作我们在上一个示例中使用的普通对象的代理。我想要这个的原因是因为我希望能够捕获此 obj 上的 getapply

请注意 return target.obj 部分 - 我们实际上仍在使用它来代理 obj - 只是我们通过 fn:

var fn = function(){};
fn.obj = {};
var p = new Proxy(fn, {
get: function(target, property, receiver) {
console.log("getting: ", property);
return target.obj[property];
}
});

现在,我原以为这会产生与上一个 "hello "+ p 示例完全相同的输出,但我错了:

getting:  Symbol(Symbol.toPrimitive)
getting: valueOf
getting: toString
getting: Symbol(Symbol.toStringTag)
"hello [object Function]"

请注意,它产生了一个 Function 字符串标记,而不是一个 Object 标记。这里发生了什么?就好像 toString 是在 fn 而不是 obj 上调用的。 (编辑: 但我们可以添加 fn.toString = function(){ return "fn"; } 它不会改变输出,所以也许它不是 fn 在这里被字符串化了?)

如果您在其中弹出一个 debugger 语句,您会看到它实际上如您所期望的那样返回 fn.obj.toString,但由于某些原因最终output 是一个函数而不是一个对象(虽然我不完全确定哪个函数)。感谢您的帮助!

附言我没有解释我的用例的完整上下文(简短版本:它用于 DSL ,所以弯曲“良好实践”很好),因此建议替代模式来实现 getapply 对象上的陷阱(实际上)可能与我的特定情况无关。我真的只是想了解为什么上述方法没有像我预期的那样工作,但也想确保这个问题足够广泛,以帮助 future 遇到类似情况的读者。

最佳答案

我想我已经找到了错误。当我们返回一个函数时,看起来我们需要将它绑定(bind)target.obj,否则它会被绑定(bind)到某处的某个函数。我对 this 的东西还不是很了解,但我认为这是有道理的。所以这是更新后的工作代码:

var fn = function(){};
fn.obj = {};
fn.toString = function(){ return "fn"; }
var p = new Proxy(fn, {
get: function(target, property, receiver) {
console.log("getting: ", property);
let result = target.obj[property];
if(typeof result === 'function') {
result = result.bind(target.obj);
}
return result;
}
});

关于javascript - 在普通 JS 对象上同时使用 `get` 和 `apply` 代理陷阱,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41917605/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com