javascript - 窗口代理

标签 javascript ecmascript-6

我想设置一个 Proxy,当在 window 对象上定义新属性时它会警告我。 (实际上我想捕获所有全局变量声明)

let handler = {
    defineProperty(target, key, descriptor) {
        console.log('hey', key);
        return false;
    }
};
window = new Proxy(window, handler);
window.foo = 'bar';
// nothing happens

上面的代码适用于除窗口之外的任何对象:

let handler = {
    defineProperty(target, key, descriptor) {
        console.log('hey', key);
        return false;
    }
};
let target = {};
target = new Proxy(target, handler);
target.foo = 'bar';
// console: "hey  bar"

有什么方法可以在window 对象上设置一个Proxy,如果不可能,是否有任何棘手的解决方案来实现相同的目标?

最佳答案

简短的回答是否定的。您不能为此使用代理。 最好修改和重构您的应用程序,以摆脱进行此类恶作剧的需要。但我知道有时候我们没有时间把事情做好。虽然我不建议您这样做,但您仍然可以更改窗口对象。

您有几个选择可以做到这一点。 如果你知道你正在寻找的变量列表,你可以使用类似 Watch.JS 的东西基本上它能够跟踪所有的变化,但我无法让它可靠地工作所以最好指定一个列表

watch(window, ['list', 'of', 'vars'], (prop, action, newVal, oldVal) => {
    console.log('Property changed', prop, action, newVal, oldVal);
}, 1);

作为替代方案,您可以创建一个简单的脏检查器

let props = Object.keys(window);
const check = () => {
    const currentProps = Object.keys(window);
    const newProps = currentProps.filter(item => props.indexOf(item) === -1);
    if (newProps.length) {
        console.log('Added these properties', newProps);
        props = currentProps;
    }
    requestAnimationFrame(check);
};
requestAnimationFrame(check);

但如果您决定采用任一解决方案,则必须确保所有检查在需要时停止以避免内存泄漏或 CPU 消耗。 这个校验码并没有消耗太多,但理论上是可以的。所以你必须留意它。 在空白页面上,配置文件数据如下所示 profile data

并且记得在 Watch.JS 的情况下使用 unwatch 或添加一个条件来停止检查,以防您在完成工作后使用第二种解决方案

关于javascript - 窗口代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45437583/

相关文章:

javascript - 为什么 jquery 链接回调中的 'this' 是 DOM 元素?

javascript - 使用 Ajax 发送数据而不发送到 PHP

javascript - 这种情况的正则表达式是什么?

javascript - @babel/plugin-transform-react-constant-elements 中的 "deopts"具体是什么意思?

javascript - 有没有一种技术可以用来使用调用函数的参数来调用函数?

javascript - 替换 JavaScript 中所有出现的字符串不起作用

javascript - 如何在没有 "borrowing"的 php 页面中包含使用 java 脚本的数字时钟,就像代码中给出的那样来自任何其他站点?

javascript - 这是在 ES6 中克隆对象的好方法吗?

javascript - 如何使用reduce()连接数组并删除重复项

javascript - Angular 中的 $q 或 ES6 中的 Promise