窗口上的代理

Ada*_*dam 11 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
Run Code Online (Sandbox Code Playgroud)

上面的代码适用于任何对象,但窗口:

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"
Run Code Online (Sandbox Code Playgroud)

有没有办法Proxywindow对象上设置,如果不可能,是否有任何棘手的解决方案来实现相同的目标?

Nik*_*nko 5

简短的回答是否定的.您不能使用代理.修改和重构你的应用程序总是更好,以摆脱这种恶作剧的需要.但我知道有时我们没时间做正确的事.通过我不建议你这样做,你仍然可以对窗口对象进行更改.

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

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

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

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);
Run Code Online (Sandbox Code Playgroud)

但是如果您决定采用任何一种解决方案,您必须确保在需要时停止所有检查以避免内存泄漏或CPU消耗.这个检查代码消耗不多,但理论上可以.所以你必须留意它.在空页面配置文件数据看起来像这样个人资料

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