admin管理员组

文章数量:1025457

If I defined some variable in outer closure, and in the inner closure has defined another variable with the same name. Can I somehow get the outer variable?

I know it's still somewhere in the memory and not been overwritten since it can be printed after the function. Is there a way to access it?

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"

If I defined some variable in outer closure, and in the inner closure has defined another variable with the same name. Can I somehow get the outer variable?

I know it's still somewhere in the memory and not been overwritten since it can be printed after the function. Is there a way to access it?

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"

Share Improve this question edited Feb 14, 2020 at 7:11 Hao Wu asked Feb 14, 2020 at 7:02 Hao WuHao Wu 21k6 gold badges36 silver badges78 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

If foo is on the top level and declared with const, one of the only ways to access it with new Function, whose scope when run is on the top level. (Please don't actually do this):

const foo = 'outer';

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

bar();

console.log(foo); // "outer"

See ment by Hao below. eval can work too, but it's a bit more plicated. As MDN says:

If you use the eval function indirectly, by invoking it via a reference other than eval, as of ECMAScript 5 it works in the global scope rather than the local scope. This means, for instance, that function declarations create global functions, and that the code being evaluated doesn't have access to local variables within the scope where it's being called.

So if you reference eval by any method other than calling the standalone variable name eval(arg), the code will run on the top level, and it will be able to see the variable on the top level:

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"

If foo is declared with var instead of const, you can just access that property of the global object:

var foo = 'outer';

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

bar();

console.log(foo); // "outer"

If the shadowed variable is not on the top level, eg

(() => {
  const foo = 'intermediate';
  (() => {
    const foo = 'inner';
    // more code here
  })();
})();

Then there's no way to access the intermediate variable from the more code here section.

I thought I'd add this answer since it might help in some situations.

const foo = 'outer';

function bar() {

  // it's ugly but it works
  {
    const foo = 'inner';
    // rest of your code
  }

  console.log(foo);   // "outer"
}

bar();

console.log(foo); // "outer"

If I defined some variable in outer closure, and in the inner closure has defined another variable with the same name. Can I somehow get the outer variable?

I know it's still somewhere in the memory and not been overwritten since it can be printed after the function. Is there a way to access it?

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"

If I defined some variable in outer closure, and in the inner closure has defined another variable with the same name. Can I somehow get the outer variable?

I know it's still somewhere in the memory and not been overwritten since it can be printed after the function. Is there a way to access it?

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"

Share Improve this question edited Feb 14, 2020 at 7:11 Hao Wu asked Feb 14, 2020 at 7:02 Hao WuHao Wu 21k6 gold badges36 silver badges78 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

If foo is on the top level and declared with const, one of the only ways to access it with new Function, whose scope when run is on the top level. (Please don't actually do this):

const foo = 'outer';

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

bar();

console.log(foo); // "outer"

See ment by Hao below. eval can work too, but it's a bit more plicated. As MDN says:

If you use the eval function indirectly, by invoking it via a reference other than eval, as of ECMAScript 5 it works in the global scope rather than the local scope. This means, for instance, that function declarations create global functions, and that the code being evaluated doesn't have access to local variables within the scope where it's being called.

So if you reference eval by any method other than calling the standalone variable name eval(arg), the code will run on the top level, and it will be able to see the variable on the top level:

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"

If foo is declared with var instead of const, you can just access that property of the global object:

var foo = 'outer';

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

bar();

console.log(foo); // "outer"

If the shadowed variable is not on the top level, eg

(() => {
  const foo = 'intermediate';
  (() => {
    const foo = 'inner';
    // more code here
  })();
})();

Then there's no way to access the intermediate variable from the more code here section.

I thought I'd add this answer since it might help in some situations.

const foo = 'outer';

function bar() {

  // it's ugly but it works
  {
    const foo = 'inner';
    // rest of your code
  }

  console.log(foo);   // "outer"
}

bar();

console.log(foo); // "outer"

本文标签: javascriptIs there a way to get outer scope variables with the same nameStack Overflow