Search code examples
node.jsscopehidden-variables

Temporarily replace global const inside function


Is there a way in Javascript to temporarily replace a variable defined in an outer scope, but only keep that value during the inner scope, as there is in other languages like C++? For example:

const debug = require('debug')('mymodule');

function example() {
    // Temporarily replace main `debug` variable with value that
    // only persists for this function
    const debug = debug.extend('myfunction');

    debug('should be in mymodule.myfunction');
}

debug('should be in mymodule');

When I try to do this, Node complains that I'm accesing the inner debug before I have defined it, when what I really want to do is access debug from the parent scope.


Solution

  • You can override the higher scoped one with a local definition. But when doing that, you can no longer access the higher scoped one.

    When you do this:

    const debug = debug.extend('myfunction');
    

    You can't access debug.extend() because the local debug has already been defined, but not yet initialized.

    The simplest solution is to just use a different named local variable. But, if you you don't want to do that and you want to retain access to the higher scoped one, you have to save a copy of it to another variable in a higher level block scope than where you define the new one so you can then access both.

    const debug = require('debug')('mymodule');
    
    function example() {
        // in a scope higher than where we define new debug variable,
        // save a copy of it so we can still access it
        const oldDebug = debug;
    
        // create another block scope to contain the new debug definition
        // and not interfere with saving the previous one above
        {
            const debug = oldDebug.extend('myfunction');
    
            debug('should be in mymodule.myfunction');
         }
    }
    
    debug('should be in mymodule');
    

    Another classic way to handle this is to pass the debug argument into your function and named the parameter something different. Then you can use both the new and the old values.

    const debug = require('debug')('mymodule');
    
    function example(oldDebug) {
        const debug = oldDebug.extend('myfunction');
        debug('should be in mymodule.myfunction');
    }
    example(debug);
    
    debug('should be in mymodule');