简体   繁体   中英

How to run code in JavaScript, only when a variable is defined?

I'm writing a simple function in JavaScript:

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

And I intend to use it as:

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

Yet I get this error:

Uncaught ReferenceError: someObjectThatWillBeDefinedLater is not defined

How do you handle this?

In simpler terms, I want to run a piece of code only when a global JSON variable is defined, and I can't determine when and where it gets defined. Sometimes it gets defined after my code, sometimes before my code, sometimes a second later, sometimes 5 seconds later. It's non-deterministic.

You can dispatch an event on the window when you define your JSON Object and add an event listener for that event on the window. This way, you will not need to use a setInterval to continuously check if a global variable is defined.

 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) 

If it's a global variable, you can pass the variable name as a string. Since global variables become properties of the window object, the function can then check whether window[objectToWaitFor] is defined.

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

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

you can do this by using

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

All global variables are attached to the window object so can pass the variable name to your function as a string and check if it exists on the window and then run your callback if it does. Snippet:

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

You can try to use metaprogramming like JS proxies to intercept the set method of an objects property. Something like this:

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

the snippet was taken from here

In your example, when the set property gets called you can check if the value meets your expected value and do as you wish with it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM