有没有办法获得具有相同名称的外部作用域变量?

Hao*_* Wu 2 javascript scope

如果我在外部闭包中定义了某个变量,而在内部闭包中定义了另一个同名的变量。我能以某种方式获得外部变量吗?

我知道它仍然在内存中的某个地方并且没有被覆盖,因为它可以在函数之后打印。有没有办法访问它?

const foo = 'outer';

function bar() {
  const foo = 'inner';

  // Is there a way to get the outside foo from here?
  console.log(foo);   // "inner", but I want it to be "outer"
}

bar();

console.log(foo); // "outer"
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 6

Iffoo位于顶层并用 声明const,这是访问它的唯一方法之一,new Function运行时其作用域在顶层。(请不要真的这样做):

const foo = 'outer';

function bar() {
  const foo = 'inner';
  const fn = new Function('return foo');
  console.log(fn('foo'));
}

bar();

console.log(foo); // "outer"
Run Code Online (Sandbox Code Playgroud)

请参阅下面 Hao 的评论。eval也可以工作,但有点复杂。正如MDN 所说

如果您间接使用 eval 函数,通过非 eval 的引用调用它,从 ECMAScript 5 开始,它在全局范围内工作,而不是在本地范围内。这意味着,例如,函数声明创建全局函数,并且被评估的代码无权访问调用它的范围内的局部变量。

因此,如果您eval通过调用独立变量 name以外任何方法进行引用eval(arg),则代码将在顶层运行,并且将能够在顶层看到该变量:

const foo = 'outer';

function bar() {
  const foo = 'inner';
  console.log(window.eval('foo'));
  // Another method:
  console.log((0, eval)('foo'))
  // Another method:
  const anotherEvalReference = eval;
  console.log(anotherEvalReference('foo'));
}

bar();

console.log(foo); // "outer"
Run Code Online (Sandbox Code Playgroud)

如果foo使用var而不是声明,则const可以访问全局对象的该属性:

var foo = 'outer';

function bar() {
  const foo = 'inner';
  console.log(window.foo);
}

bar();

console.log(foo); // "outer"
Run Code Online (Sandbox Code Playgroud)

如果阴影变量不在顶层,例如

(() => {
  const foo = 'intermediate';
  (() => {
    const foo = 'inner';
    // more code here
  })();
})();
Run Code Online (Sandbox Code Playgroud)

那么就无法intermediate从该more code here部分访问该变量。