【问题标题】:Temporarily replace global const inside function临时替换函数内部的全局常量
【发布时间】:2020-01-19 03:11:01
【问题描述】:

在 Javascript 中是否有一种方法可以临时替换在外部范围中定义的变量,但只在内部范围内保留该值,就像在 C++ 等其他语言中一样?例如:

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

当我尝试这样做时,Node 抱怨说我在定义它之前访问了内部 debug,而我真正想做的是从父范围访问 debug

【问题讨论】:

  • 你可以用一个本地声明的变量覆盖更高范围的变量,但是你不能访问更高范围的变量。
  • @jfriend00:从技术上讲,我不需要在本地定义后访问更高范围的,因为我希望本地在函数期间替换它。跨度>
  • 但是,你不能这样做 const debug = debug.extend('myfunction'); 因为新的 const debug 已经在这个块作用域中定义(但没有初始化)所以你不能再访问你正在尝试的更高作用域的那个到。所有const 变量都被“提升”到其范围的顶部,因此它已经在声明它的块的开头覆盖/隐藏了更高范围的变量。
  • 是的,所以我希望有人想出一个聪明的解决方案来解决这个问题:-)
  • 好吧,您可以将更高范围的变量保存到一个不同命名的变量中,然后在您定义本地覆盖的地方引入一个新的块范围。然后,您可以访问更高范围的副本和新定义的副本。看我的回答。

标签: node.js scope hidden-variables


【解决方案1】:

您可以使用本地定义覆盖更高范围的。但是这样做时,您将无法再访问更高范围的。

当你这样做时:

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

你不能访问debug.extend(),因为本地的debug已经定义好了,但是还没有初始化。

最简单的解决方案是使用不同的命名局部变量。但是,如果您不想这样做并且希望保留对更高范围的访问权限,则必须将其副本保存到比您定义新的更高级别的块范围中的另一个变量,以便您然后可以访问两者。

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

另一种处理此问题的经典方法是将debug 参数传递到您的函数中,并将参数命名为不同的名称。然后您可以同时使用新值和旧值。

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

【讨论】:

  • 这与我最终做的类似,尽管我在顶层添加了const g_debug = debug,并在函数本身中使用了const debug = g_debug.extend()。不过还是有点乱,所以我希望有更好的东西!
  • 添加了另一个选项,将更高范围的变量传递给您的函数并给参数一个不同的名称。这比创建新的块范围更干净。
【解决方案2】:

可能有更好的解决方案,但我让它像这样工作:

debug = 'foo';

function example() {
  const debug = this.debug + 'bar';
  console.log(debug); // prints 'foobar'
}

example();
console.log(debug); // prints 'foo'

或者,如果您想保留 const 关键字:

const debug = 'foo';

function example(debugRef) {
  const debug = debugRef + 'bar';
  console.log(debug); // prints 'foobar'
}

example(debug);
console.log(debug); // prints 'foo'

【讨论】:

  • 我真的很希望这样做而不必为我的所有函数添加额外的参数,因为它们有很多,它会使代码非常混乱!
  • @Malvineous yupp!我也是。标记为收藏,希望我们能得到更好的答案,因为我去过那里,并强迫自己为变量选择不同的名称..
猜你喜欢
  • 2022-08-02
  • 2020-04-04
  • 1970-01-01
  • 2022-10-14
  • 2013-07-13
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 1970-01-01
相关资源
最近更新 更多