1

请原谅我的n00bility ...我正在尝试使用代理在全局var阶段不再未定义之后执行一些代码。这是我天真的尝试:

```

var stage = undefined
let myObj;
let st = {
    stage: stage,
}
let lr = {
    get: function(obj:any, prop:any):LightRay{
        myObj = new SomeObjThatNeedsStage(obj[prop]) // <= supposed to be non-undefined stage
        return myObj
    },
}
let p = new Proxy(st, lr)
// At this point I expect the lr handler to have been executed if the stage var has been instantiated by some external code that's out of my control.

```

显然,我误解了代理的工作原理,但我尝试了各种方案,但都不起作用。将未定义阶段作为目标传递给代理不起作用(Cannot create proxy with a non-object as target or handler出现错误)。在这种情况下如何使用代理?为什么在实例化之前我不能observe使用代理的未定义阶段,然后执行回调?

供参考:

Stage var 是全局变量,我无法控制它(它在某些时候由 create.js 实例化)。所有代码都从 UMD 模块执行。我正在使用打字稿(转译为 es5)。Object.defineProperty() 在我的浏览器中可用。此外,阶段(createjs.Stage 类型)在实例化时确实包含不同类型的 setter/getter,这在使用 typescript 时会出现问题。

4

2 回答 2

1

更新的答案

你说过你不控制如何stage设置。

观察变化是反模式和代码维护的噩梦。尽可能寻找任何其他解决方案,例如使一个模块依赖于另一个模块,以便您知道它在模块运行之前已加载。

但是,您已经说过没有其他方法,所以:

您不能为此使用代理,因为为了使其生效,代码设置stage必须通过代理进行设置,而不是直接设置。

你说过你不控制如何stage声明。这意味着您也不能Object.defineProperty为此使用,因为var创建的全局对象上的属性具有configurable: false.

如果绝对没有办法在你的模块和正在做的事情之间取得协调stage,你将不得不求助于计时器循环。这不是一个好主意,但可能是您唯一真正的选择:

var stop = Date.now() + 30000;
var timer = setInterval(function() {
    if (typeof stage !== "undefined" || Date.now() > stop) {
        clearInterval(timer);
        timer = 0;
        // Your code here, if `stage` is still undefined, you hit the timeout
    }
}, 50); // 50ms interval or whatever you need

原始答案

到目前为止,最好的解决方案是:不要那样做。相反,使用带有 setter 的对象:

var stuff = {
    _stage: undefined,
    get stage() {
        return _stage;
    },
    set stage(value) {
        if (_stage === undefined && value !== undefined) {
            _stage = value;
            // Trigger your code here
        }
    }
};

然后让其他代码执行此设置stuff.stage而不是设置stage

于 2018-04-17T10:52:31.887 回答
0

如果你真的需要stage在它被其他东西定义并且stage是全局的时观察变化,那么简单的解决方案是使用旧的好 getter:

let myObj;

Object.defineProperty(window, 'stage1', {
  set (value) {
    myObj = new SomeObjThatNeedsStage(stage)
    return value
  }
})

在上面,确保你没有var stage = undefined你不再需要它。

于 2018-04-17T10:54:42.900 回答