简体   繁体   English

为什么在try块中重新声明函数标识符会抛出SyntaxError?

[英]Why does redeclaring a function identifier within a try block throw a SyntaxError?

The following lines of JavaScript 以下几行JavaScript

try {
    function _free() {}
    var _free = 1;
} finally { }

result in the following error: 导致以下错误:

 Uncaught SyntaxError: Identifier '_free' has already been declared

However, the following two blocks of JavaScript code don't: 但是,以下两个JavaScript代码块不会:

  1. Without the try block scope: 没有try块范围:

     function _free() {} var _free = 1; 
  2. Within a function scope: function范围内:

     function a() { function _free() {} var _free = 1; } 

But why? 但为什么?

(Testing environment: Chromium 61.0.3126.0) (测试环境:Chromium 61.0.3126.0)

因为块范围的函数声明是新的ES6特性并且是安全的(即在名称冲突上抛出错误,类似于letconst ),但是其他情况(无论是程序员错误)都需要保持向后兼容并静默覆盖功能。

To expand on Bergis answer , there is a difference in how the code is interpreted in ES5 and ES6 since block-scoped function declarations were added. 为了扩展Bergis的答案 ,自从添加了块范围的函数声明以来,在ES5和ES6中如何解释代码是有区别的。

Input: 输入:

function test() {
    try {
        function _free() { }
        var _free = 1;
    } finally { }
}

Since ES5 does not support block-level functions, _free is hoisted to the parent function: 由于ES5不支持块级函数,因此_free提升到父函数:

function test() {
    var _free = function _free() { }
    try {
        var _free = 1;
    } finally { }
}

In ES6, the function is declared at block-level, and semantically equal to a let / const declaration: 在ES6中,函数在块级声明,并在语义上等于let / const声明:

function test() {
    try {
        let _free = function _free() { }
        var _free = 1;
    } finally { }
}

This throws an error because var _free tries to declare a variable which is already declared. 这会引发错误,因为var _free尝试声明声明的变量。 For example, this throws in ES6 as well: 例如,这也引发了ES6:

let _free;
var _free = 1;    // SyntaxError: Indentifier '_free' has already been declared

While this is fine: 这很好:

var _free;
var _free = 1;    // No SyntaxError

Setting the value of the already declared identifier is fine: 设置已声明的标识符的值是正常的:

let _free;
_free = 1;

Therefore, to set the declared identifier _free to 1, you need to skip the second declaration : 因此,要将声明的标识符_free设置为1,您需要跳过第二个声明

try {
    function _free() { }
    _free = 1;
} finally { }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在 function 中重新声明标识符,会屏蔽同名参数? - Why does redeclaring an identifier in a function, mask a parameter of the same name? 为什么会抛出一个SyntaxError? - Why does this throw a SyntaxError? 谁能告诉我为什么 try 块中的 setTimeout function 不起作用? - Could anyone tell me why my setTimeout function within the try block does not work? async function try catch 块是否可以包装一个也可能引发错误的调用 async function? - Does async function try catch block can wrap a called async function that also may throw an error? 为什么在eval()中的typeof会在我的函数中抛出错误? - Why does typeof within eval() throw an error in my function? 为什么gulp-sprite-generator会抛出“ SyntaxError:意外令牌;”? - Why does gulp-sprite-generator throw “SyntaxError: Unexpected token ;”? 开玩笑抛出错误 SyntaxError: Unexpected identifier - Jest throw error SyntaxError: Unexpected identifier 使用import语句,为什么会失败并显示“ Uncaught SyntaxError:Unexpected identifier” - Using import statement, why does it fail with “Uncaught SyntaxError: Unexpected identifier”" 为什么直接在Object文字上访问属性会抛出一个SyntaxError? - Why does accessing a property directly on an Object literal throw a SyntaxError? 为什么在三元运算符内部返回会抛出 SyntaxError? - Why does returning inside the ternary operator throw a SyntaxError?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM