我正在尝试使用const
声明一堆常量。我的问题是在Firebug控制台中测试代码会引发错误,抱怨'重新声明const foo'。
我试图将它包装在try{}catch(e){}
块中,但这没有帮助,甚至在尝试使用以下代码绕过它时(发布减去所有console.info()“调试”调用为了清楚起见)它仍然会在第二次运行时抛出错误:
if(!chk_constsDeclaredYet) {
var chk_constsDeclaredYet = true;
const foo="bar";
}
我的问题是,当const在if(){}中时,当代码第二次“运行”时,为什么const foo甚至被查看?
注意:代码将在firebug javascript控制台中运行,我想要实现的工作流程是:
firebug输出:
//FIRST RUN::
>>> console.group() console.info('--code start--'); ...console.info('--code end--'); console.groupEnd()
--code start--
chk_constsDeclaredYet = undefined
foo = undefined
--if()--
--if() running..--
--end if()--
chk_constsDeclaredYet = true
foo = bar
--code end--
//SECOND RUN::
>>> console.group() console.info('--code start--'); ...console.info('--code end--'); console.groupEnd()
TypeError: redeclaration of const foo { message="redeclaration of const foo", more...}
答案 0 :(得分:4)
这是一个老问题的答案。我写了一个slightly newer answer处理类似的“const重新赋值/范围”问题,其中我表明所产生的错误(如果有的话)因执行方法和浏览器而异。
由于const
(不是ECMAScript第5版标准的一部分)将在ECMAScript第6版中具有不同的含义,我建议在当前代码中避免使用 。 / p>
const
,与var
一样,是“功能范围”。我怀疑问题来自var
上与绑定相同类型的“to top of function”促销(这解释了为什么异常没有来自作业,但来自宣言)。也就是说,任何后续的const x = ...
,无论它们出现在哪里,都被认为是无效的,因为先前的声明已经存在(根据定义,只能有给定名称的一个const)每个范围)。但是,const
可以采用任何值,因此分配在const x = ...
网站上发生,就像在var x = ...
网站上进行分配一样,即使注释也是如此/ binding被提升到范围的顶部。
这是一个简单的测试用例,可以更清楚地说明问题:
function x () { if (true) { const a = 1 } else { const a = 2 }}
// => TypeError: redeclaration of const a @ <x-jsd:interactive-session
如您所见,错误发生在函数执行时的函数声明和不处。这就是try / catch不起作用的原因。行为也可能受到您正在处理的交互式工具的影响,具体取决于它执行代码的方式(例如,每次都是相同的执行上下文?)。
但是,这样做很好,并强化了上面的初始命题:
(function x() { if (false) { const c = 1 }; return c })()
// => undefined
来自https://developer.mozilla.org/en/JavaScript/Reference/Statements/const
(大胆加重)
创建一个常量,该常量可以是声明它的函数的全局或局部。 常量遵循与变量相同的范围规则。
常量的值不能通过重新赋值来改变,并且不能重新声明常量。因此,尽管可以在不初始化的情况下声明常量,但这样做是没用的。
常量不能与同一范围内的函数或变量共享其名称。
const是一个特定于Mozilla的扩展,IE不支持它,但自9.0版和Safari版以来,Opera已部分支持它。
答案 1 :(得分:1)
const
类型应始终等于常量值。如果if
语句可以更改常量的值,则它应该是var
,因为它的值可能会有所不同。
但您遇到的问题似乎是因为您将常量值设置为两次。您在代码第一次运行时初始化常量。由于常量在再次运行时具有值,因此会出现异常。如果将const foo = 'bar';
移到脚本顶部,则不会发现该问题。但是,如果您希望根据逻辑更改该值,则需要var
。
修改强>
如果您阅读了异常消息,则会显示“重新声明const foo”。这意味着你不能两次声明foo。现在在控制台中,每次运行代码(没有刷新)时,先前的变量仍然在范围内。所以从理论上讲,即使你只在代码中看到一次,你也会多次声明const foo。你不能将它包装在if / else块中,因为它仍然需要const foo ='bar',这仍然是一个非法声明。
您可能不得不在运行更改的代码之间刷新页面。
答案 2 :(得分:0)
我不知道这是不是最好的方法,但是eval
会让你解决这个问题:
if( !chk_constsDeclaredYet ){ eval("const foo = \"bar\"") }