let Variable Scope

我的梦境 提交于 2021-02-04 19:55:32

问题


The following code will output "1." However, shouldn't the keyword "let" not make x a global variable, thus making it invisible to das()? let is supposed to limit the scope of variables to only the block where they're declared, yet here, I'm seeing an inner function have access to a "let" variable, even though x was declared outside its scope. How is that possible?

function letTest() {
	function das () {
		console.log(x);
// How does this function have access to a let variable declared outside its scope?
	}

	let x = 1;
	das();
}
letTest();

回答1:


Here's a way of thinking about how let works:

  1. Start from the let.
  2. At the same nesting level, working back/up through the source code, find the first {.
  3. Now from the let find the corresponding }.

That gives you the scope wherein the variable will be visible. If a function definition appears in that scope, fine; the variable is visible to code in that function.

Now, what's a little bit weird is that in your example the variable looks like it's used in the scope before it's declared. That's where the fact that the reference appears before the declaration becomes a little more interesting.

Normally, if code in a scope refers to a let-declared variable before the let actually happens, that's an error. However, that's a runtime thing, not a syntax thing. In your case, at runtime the let will have "happened" by the time the nested function is called.




回答2:


let limits the scope of the variable to the current block (in this case that is the same as the letTest function).

The das function is declared inside that scope, so it has access to anything in that scope (including x).




回答3:


The thing is that you are not mutating the value of x, in your case you are just logging it to the console and they are all nested under one scope which does not limit the inner function, so your result is expected.

Now if you did something like this

function letTest() {
    function das () {
        console.log(x);
// How does this function have access to a let variable declared outside its scope?
    }
    let x = 1;
    function change(){
       x = x + 1;
    }

    change();
}
letTest();

Now you are trying to change the value of x and the compiler would complain.




回答4:


The function is declared in the same block as x, so the code inside the function has access to x.

If you don't want that, you can always add a new block:

function letTest() {
  function das () {
    console.log(x); // ReferenceError
  }
  { // New block
    let x = 1;
    das();
  }
}
letTest();



回答5:


@GTS Joe,

the let x is local to the letTest() context, therefore das() is simply accessing its xvariable. Nothing strange is going on there. So, 'no' - it's not becoming global.

No matter how deep the context of the variable call has been nested, there's always a look-up JS principle, that will follow on a failed look around and will continue to look up for this variable name all the way through the global scope, and only then - when nothing's found - it will cause a reference error.

And that - only because there's no look below JS principle - the so called closures are possible.




回答6:


As described here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let it provides access within the block scope. As your das() execution and x declaration are in the same block scope it will have access.

A good example is in the switch case below, using var x = 'x' in case 1 will cause it to attach to the function scope and accessible in the console.log() but when trying to reference the bar variable for logging it throws a reference exception. But still works in the default case.

const example = (foo) => {
    switch(foo) {
        case 0:
            break;
        case 1:
            let bar = 'bar';
            var x = 'x';
            break;
        default:
            console.log(bar);
            break;
    }

    console.log(x);
    console.log(bar);
}

example(1);


来源:https://stackoverflow.com/questions/41337338/let-variable-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!