¿Por qué un retorno en `finally` anula 'try'?


¿Cómo funciona una sentencia return dentro de un bloque try/catch?

function example() {
    try {
        return true;
    }
    finally {
        return false;
    }
}

Espero que la salida de esta función sea true, pero en cambio es false!

Author: chharvey, 2010-10-01

7 answers

Finalmente siempre se ejecuta. Para eso es, lo que significa que su retorno se usa en tu caso.

Querrá cambiar su código para que sea más como esto:

function example() { 
    var returnState = false; // initialisation value is really up to the design
    try { 
        returnState = true; 
    } 
    catch {
        returnState = false;
    }
    finally { 
        return returnState; 
    } 
} 

En términos generales, nunca desea tener más de una declaración de retorno en una función, cosas como esta son la razón.

 68
Author: annakata,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-01 09:45:35

Según ECMA-262 (5ed, diciembre de 2009), en pp. 96:

La producción TryStatement : try Block Finally se evalúa de la siguiente manera:

  1. Sea B el resultado del Bloque de evaluación.
  2. Sea F el resultado de evaluar Finalmente.
  3. Si F. type es normal, devuelve B.
  4. Devuelve F.

Y de la página 36:

El tipo de Terminación se utiliza para explicar el comportamiento de las declaraciones (break, continue, return y throw) que realizar transferencias de control no locales. Los valores del tipo de terminación son triples del formulario (type, value, target) , donde type es uno de normal, break, continue, return, o throw, value es cualquier valor de lenguaje ECMAScript o vacío, y target es cualquier identificador ECMAScript o vacío.

Está claro que return false establecería el tipo de finalización de finalmente como return, lo que hace que try ... finally haga 4. Devuelve F .

 27
Author: livibetter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-21 04:31:56

Cuando se usa finally, cualquier código dentro de ese bloque se dispara antes de que salga el método. Debido a que está utilizando un retorno en el bloque finally, llama a return false y anula el anterior return true en el bloque try.

(La terminología podría no ser del todo correcta.)

 10
Author: GenericTypeTea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-01 09:42:42

Por qué estás obteniendo false es que regresaste en un bloque finally. finalmente bloque debe ejecutar siempre. así que su return true cambia a return false

function example() {
    try {
        return true;
    }
    catch {
        return false;
    }
}
 3
Author: anishMarokey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-01 09:43:33

Por lo que sé, el bloque finally siempre se ejecuta, independientemente de si tiene una instrucción return dentro de try o no. Ergo, obtiene el valor devuelto por la instrucción return dentro de finally block.

He probado esto con Firefox 3.6.10 y Chrome 6.0.472.63 tanto en Ubuntu. Es posible que este código se comporte de manera diferente en otros navegadores.

 0
Author: Manoj Govindan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-01 09:43:22

Finalmente se supone que SIEMPRE se ejecuta al final de un bloque try catch para que (por especificación) sea la razón por la que se devuelve false. Tenga en cuenta que es completamente posible que diferentes navegadores tengan diferentes implementaciones.

 -1
Author: Darko Z,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-05 00:09:46

¿Qué pasa con esto?

doubleReturn();

function doubleReturn() {
  let sex = 'boy';

  try {
    return sex;

    console.log('this never gets called...');
  } catch (e) {} finally {
    sex = 'girl'; 

    alert(sex);
  }
}
 -1
Author: Thomas Karlsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-28 20:53:53