javascript - usar - ¿Por qué la redeclaración de un identificador de función dentro de un bloque de prueba lanza un error de sintaxis?
try catch nodejs (2)
Debido a que las declaraciones de funciones de ámbito de bloque son una nueva característica de ES6 y se hicieron seguras (es decir, lanzan un error en las colisiones de nombres, similar a let
y const
), pero los otros casos (que son errores del programador independientemente) se necesitaron para mantener la compatibilidad hacia atrás y sobrescribir silenciosamente la función.
Las siguientes líneas de JavaScript.
try {
function _free() {}
var _free = 1;
} finally { }
dar como resultado el siguiente error:
Uncaught SyntaxError: Identifier ''_free'' has already been declared
Sin embargo, los siguientes dos bloques de código JavaScript no:
Sin el alcance del bloque
try
:function _free() {} var _free = 1;
Dentro de un ámbito de
function
:function a() { function _free() {} var _free = 1; }
¿Pero por qué?
(Ambiente de prueba: cromo 61.0.3126.0)
Para ampliar la respuesta de Bergis , hay una diferencia en cómo se interpreta el código en ES5 y ES6 desde que se agregaron las declaraciones de funciones de ámbito de bloque.
Entrada:
function test() {
try {
function _free() { }
var _free = 1;
} finally { }
}
Como ES5 no admite funciones de nivel de bloque, _free
se hoisted a la función principal:
function test() {
var _free = function _free() { }
try {
var _free = 1;
} finally { }
}
En ES6, la función se declara a nivel de bloque, y semánticamente igual a una declaración let
/ const
:
function test() {
try {
let _free = function _free() { }
var _free = 1;
} finally { }
}
Esto var _free
un error porque var _free
intenta declarar una variable que ya está declarada. Por ejemplo, esto arroja en ES6 también:
let _free;
var _free = 1; // SyntaxError: Indentifier ''_free'' has already been declared
Si bien esto está bien:
var _free;
var _free = 1; // No SyntaxError
La configuración del valor del identificador ya declarado está bien:
let _free;
_free = 1;
Por lo tanto, para establecer el identificador declarado _free
en 1, debe omitir la segunda declaración :
try {
function _free() { }
_free = 1;
} finally { }