Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/435.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用代理查看变量是否(不再)未定义_Javascript_Ecmascript 6_Es6 Proxy - Fatal编程技术网

Javascript 如何使用代理查看变量是否(不再)未定义

Javascript 如何使用代理查看变量是否(不再)未定义,javascript,ecmascript-6,es6-proxy,Javascript,Ecmascript 6,Es6 Proxy,请原谅我的错误。。。 在全局变量阶段不再未定义之后,我尝试使用代理来执行一些代码。以下是我天真的尝试: ``` var阶段=未定义 让myObj; 设st={ 阶段:阶段,, } 设lr={ 获取:函数(对象:任意,属性:任意):LightRay{ myObj=newsomeobjthatneedstage(obj[prop])//更新的答案 您说过您无法控制阶段的设置方式 监视更改是一个反模式和代码维护的噩梦。寻找任何其他可以的解决方案,例如使一个模块依赖于另一个模块,以便在模块运行之前知道

请原谅我的错误。。。 在全局变量阶段不再未定义之后,我尝试使用代理来执行一些代码。以下是我天真的尝试:

```

var阶段=未定义
让myObj;
设st={
阶段:阶段,,
}
设lr={
获取:函数(对象:任意,属性:任意):LightRay{
myObj=newsomeobjthatneedstage(obj[prop])//更新的答案
您说过您无法控制
阶段的设置方式

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

但是,你说过没有其他办法,所以:

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

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

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

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
        }
    }
};

然后让另一个代码做这个设置。如果你真的需要观察
stage
被其他东西定义时的变化,并且
stage
是全局的,那么简单的解决方案是使用旧的good getter:

let myObj;

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

在上面的例子中,确保你没有
var stage=undefined
你不再需要它了。

这听起来像是一个问题。你为什么认为你想写代码来监视全局变量的值发生变化?应该定义什么
stage
变量?仅供参考:监视变化是一种反模式和代码维护噩梦。寻找任何其他解决方案,比如让一个模块依赖于另一个模块,以便在模块运行之前知道它已加载。是的,我知道这是一个坏主意,但我必须处理它,因为Adobe Animate CC导出Create.js代码和Create.js的奇怪方式令人烦恼地没有发出('ready'))事件,该事件将告诉我该阶段已启动并正在运行。这不在我的控制范围内。“在这种情况下,我如何使用代理?”-您不能。我们可以使用
对象。defineProperty
用于此目的?@zabusa:是的,但不能保证使用主机提供的对象。(也就是说:它可能与
窗口
/全局对象一起工作。)是的,Windows/document和getter从未出现过问题。@dfsq:很好。浏览器在过去几年中在使其主机提供的对象与JS兼容方面做得非常好。啊,对不起,我的回答很匆忙。没有对更新的版本给予足够的关注。我很抱歉。只是仔细看看你的回答。本质上是sa我,你的还有一个额外的好处,就是定时器超时时间太长了,所以我撤销了我的答案。你的答案肯定更好。干杯……提供的
defineProperty
可以在全局对象上工作,在浏览器上是主机提供的;主机提供的对象不一定要支持它。另外:
set
不应该eturn该值,您可能需要一个
get
。无法工作。setter从未被调用。顺便说一句,是的,stage是全局的,我无法控制它。您提供的代码是从UMD模块执行的。我正在使用typescript(向下传输到es5)。Object.defineProperty()在我的浏览器中可用。