让变量范围

时间:2016-12-26 23:42:57

标签: javascript variables let

以下代码将输出“1”。但是,关键字“let”不应该使x不是全局变量,因此它对das()不可见吗? let应该将变量的范围限制为仅声明它们的块,但是在这里,我看到内部函数可以访问“let”变量,即使x被声明在其范围之外。怎么可能?

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

7 个答案:

答案 0 :(得分:3)

这是一种思考let如何运作的方式:

  1. let
  2. 开始
  3. 在相同的嵌套级别,通过源代码返回工作,找到第一个{
  4. 现在从let找到相应的}
  5. 这为您提供了变量可见的范围。如果函数定义出现在该范围内,则很好;该变量对该函数中的代码可见。

    现在, little 有点奇怪的是,在你的例子中,变量看起来像它在声明之前在范围中使用。这就是参考在声明之前出现的事实变得更有趣。

    通常,如果范围中的代码在let实际发生之前引用了let - 声明的变量,那就是错误。但是,这是一个运行时的东西,而不是语法的东西。在您的情况下,在运行时,let将在调用嵌套函数时“发生”。

答案 1 :(得分:1)

let将变量的范围限制为当前块(在这种情况下,与letTest函数相同)。

das函数在该范围内声明,因此它可以访问该范围内的任何内容(包括x)。

答案 2 :(得分:0)

问题是你没有改变x的值,在你的情况下,你只是将它记录到控制台,它们都嵌套在一个范围内,不限制内部函数,所以你的结果是预期的。 / p>

现在,如果你做了类似的事情

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

现在您正在尝试更改x的值,编译器会抱怨。

答案 3 :(得分:0)

如此处所述:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let它在块范围内提供访问权限。由于您的das()执行和x声明位于同一块范围内,因此它将具有访问权限。

一个很好的例子是在下面的switch案例中,在案例1中使用var x = 'x'会导致它附加到函数作用域并且可以在console.log()中访问,但是当尝试引用bar变量进行日志记录时它抛出一个引用异常。但仍然适用于默认情况。

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

答案 4 :(得分:0)

该函数在与x相同的块中声明,因此函数内的代码可以访问x

如果您不想要,可以随时添加新块:



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




答案 5 :(得分:0)

@GTS Joe,

let xletTest()上下文的本地,因此das()只是访问其x变量。那里没什么奇怪的。所以,'不' - 它没有变得全球化。

无论嵌套变量调用的 context 有多深,总有一个查找 JS原则 < / strong>,这将会在失败的 环顾 后继续,并将继续在全局范围内查找此变量名称,并且只有这样 - 当没有任何内容时发现 - 它会引起参考错误。

而且 - 只是因为没有看下面 JS原则 - 所谓的闭包是可能的。

答案 6 :(得分:-1)

它不在范围之外。 xdas() 定义在同一个块作用域中。该块中的任何其他内容都可以访问 x。这包括任何嵌套函数、for 循环、while 循环和 if 条件。这包括 elseif 条件中的 elseif