仅在定义变量后,如何在JavaScript中运行代码?

时间:2019-03-09 20:00:33

标签: javascript

我正在用JavaScript编写一个简单的函数:

function waitThenRun(objectToWaitFor, callback) {
   // logic to periodically check for objectToWaitFor to become something
   // then call the callback
}

我打算将其用作:

waitThenRun(someObjectThatWillBeDefinedLater, function() {
    // Doing something with someObjectThatWillBeDefinedLater
});

但我收到此错误:

  

未捕获的ReferenceError:someObjectThatWillBeDefinedLater不是   定义

您如何处理?

简单来说,我只想在定义了全局JSON变量时才运行一段代码,而无法确定何时何地定义它。有时,它是在我的代码之后定义的,有时在我的代码之前,有时是一秒钟后,有时是5秒后定义。这是不确定的。

5 个答案:

答案 0 :(得分:1)

在定义JSON对象并在窗口上为该事件添加事件侦听器时,可以在window上调度事件。这样,您将不需要使用setInterval来连续检查是否定义了全局变量。

function defineJSON(){
  window.JSONObj = {x: "something"};
  triggerEvent("JSONDefined", window, {JSONObjName: "JSONObj"});//fire a custom event on the window when you define the JSON Object
}
function triggerEvent(type, obj, data){
  var ev;
  if (document.createEvent) {
    ev = document.createEvent("HTMLEvents");
    ev.initEvent(type, true, true);
  } else {
    ev = document.createEventObject();
    ev.eventType = type;
  }
  ev.eventName = type;
  if(data){
   for(var key in data){
     if(data.hasOwnProperty(key)){
        ev[key] = data[key];
     }
   }
  }
  if (document.createEvent) {
    obj.dispatchEvent(ev);
  } else {
    obj.fireEvent("on" + ev.eventType, ev);//for < IE8
  }
}
window.addEventListener("JSONDefined", function(ev){
  //this event handler will be called when the JSON Object is defined
  console.log("JSON defined:", window[ev.JSONObjName]);
});
setTimeout(function(){
   defineJSON();
}, 2000);//define JSON Object after 2 seconds (just for this example)

答案 1 :(得分:0)

如果它是全局变量,则可以将变量名称作为字符串传递。由于全局变量成为window对象的属性,因此该函数可以检查是否定义了window[objectToWaitFor]

function waitThenRun(objectToWaitFor, callback) {
    var interval = setInterval(function() {
        if (window[objectToWaitFor] !== undefined) {
            clearInterval(interval);
            callback();
        }
    }            
}

waitThenRun("someObjectThatWillBeDefinedLater", function() {
    // do something with someObjectThatWillBeDefinedLater
});

答案 2 :(得分:0)

您可以使用

   var checkExist = setInterval(function() {
   if (JsonObject) {
//execute your method here
      console.log("Exists!");
      clearInterval(checkExist);
   }
}, 100); // check every 100ms

答案 3 :(得分:0)

所有全局变量都附加到window对象上,因此可以将变量名称作为字符串传递给您的函数,并检查变量名是否存在于window上,然后运行回调(如果存在)。片段:

setTimeout(function() {
  window.someObjectThatWillBeDefinedLater = {hello: 'world'};
}, 1000);

function waitThenRun(globalObj, callback) {
  let intervalId = setInterval(function() {
    if (window[globalObj] !== undefined) {
      callback(window[globalObj]);
      clearInterval(intervalId);
    }
  }, 200);
}

waitThenRun('someObjectThatWillBeDefinedLater', console.log.bind(console));

答案 4 :(得分:0)

您可以尝试使用像JS代理这样的元编程来拦截objects属性的set方法。像这样:

function tracePropAccess(obj, propKeys) {
    const propKeySet = new Set(propKeys);
    return new Proxy(obj, {
        get(target, propKey, receiver) {
            if (propKeySet.has(propKey)) {
                console.log('GET '+propKey);
            }
            return Reflect.get(target, propKey, receiver);
        },
        set(target, propKey, value, receiver) {
            if (propKeySet.has(propKey)) {
                console.log('SET '+propKey+'='+value);
            }
            return Reflect.set(target, propKey, value, receiver);
        },
    });
}

摘录摘自here

在您的示例中,当set属性被调用时,您可以检查该值是否符合期望值,并随心所欲地对其进行操作。