范围如何在这种情况下工作?

时间:2018-01-23 06:44:01

标签: javascript ecmascript-6 const

为什么这段代码会在if块中抛出错误, ReferenceError: x is not defined?我理解定义另一个名为x的变量看起来不对,但是在定义新的const x时不应该抛出错误吗?

'use strict'

function task() {
    const x = 5
    return _subTask({x, condition: true})
}


function _subTask({x, condition}) {
    if (condition) {
        const y = x * 10
        const x = y * 10
        return x
    } else {
        return 0
    }
}
console.log(task())

4 个答案:

答案 0 :(得分:2)

这是因为时间死区(TDZ)。当访问letconst变量时,该变量在代码的后半部分中定义,它被称为在TDZ中,并且将抛出ReferenceErrorletconst变量不会升起。您可以在this page中了解有关TDZ的更多信息。

在您的情况下,您的意思是使用我假设的语句x中函数参数的const y = x * 10值。由于您已在该范围内本地声明x,因此优先级更高。当控件达到x时,const y = x * 10位于TDZ中,访问它会引发该错误。

要解决此问题,您需要在其中一个位置使用不同的变量名称而不是x。作为一般的良好实践,始终使用唯一的变量名称。

在您的具体情况下,除非您需要从多个地方调用_subtask功能,否则您可以像这样简化task实施

function task() {
  const x = 5;
  return (condition ? x * 100 : 0);
}

答案 1 :(得分:1)

  

我理解定义另一个名为x的变量看起来是错误的,但是   在定义新的const x时,不应该抛出错误吗?

x成为const之前,在{if}阻止中defined 之前无法访问。

但是,可以在if

之前访问它

function task() 
{
    const x = 5
    return _subTask({x, condition: true})
}
function _subTask({x, condition}) 
{
    console.log(x); //this will print fine 
    if (condition) {
        const y = x * 10 //also this will  give an error
        const x = y * 10
        return x
    } else {
        return 0
    }
}
console.log(task())

您可以修改代码(不含const

function _subTask({x, condition}) 
{
    return condition ? (x * 10 * 10) : 0;
}

答案 2 :(得分:1)

此处的错误称为临时死区(TDZ)。根据ES6,如果块中有let或const。在let或const声明之前,无法访问该变量。

{
   // TDZ start here
   // x can not been accessed
   const y = x * 10
   const x = y * 10
   return x
}

答案 3 :(得分:0)

 if (condition) {
    const y = x * 10;
    {
      const x = y * 10
      return x;
    }
}

x声明中的y现在引用了解构的参数,因为本地定义包含在另一个块中。