Почему возврат в "finally" переопределяет "try"?


как работает оператор return внутри блока try/catch?

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

Я ожидаю, что выход этой функции будет true, а false!

7 63

7 ответов:

наконец-то всегда выполняет. Вот для чего он нужен, а это значит, что его возврат используется в вашем случае.

вы хотите изменить свой код так что это больше похоже на это:

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

вообще говоря, вы никогда не хотите иметь более одного оператора return в функции, поэтому такие вещи, как это.

согласно ECMA-262 (5ed, декабрь 2009), в стр. 96:

производства TryStatement : try Block Finally вычисляется следующим образом:

  1. пусть B-результат вычисления блока.
  2. пусть F-результат окончательной оценки.
  3. если тип F. нормальный, верните B.
  4. Возвратить Ф.

и из стр. 36:

тип завершения используется для объяснения поведение высказываний (break,continue,return и throw), которые выполняют нелокальной передачи управления. Значения типа завершения являются тройками формы (тип, значение, цели), где тип один из normal,break,continue,return или throw,стоимостью любое значение языка ECMAScript или пустое, и цель - это любой идентификатор ECMAScript или пустой.

понятно, что return false установить тип завершения наконец-то как return, которые вызывают try ... finally сделать 4. Возвращение Ф.

при использовании finally, любой код в этом блоке срабатывает до выхода метода. Потому что вы используете возврат в finally блок, он называет return false и переопределяет предыдущие return true на try блок.

(терминология может быть не совсем правильно.)

почему вы получаете false, вы возвращаетесь в блок finally. наконец блок должен выполняться всегда. так что ваш return true изменения return false

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

насколько я знаю,finally блок всегда выполняется, независимо от того, есть ли у вас return инструкция try или нет. Следовательно, вы получаете значение, возвращаемое return оператор внутри блока finally.

Я проверил это с Firefox 3.6.10 и Chrome 6.0.472.63 как в Ubuntu. Возможно, что этот код может вести себя по-разному в других браузерах.

наконец, предполагается, что всегда выполняется в конце блока try catch, так что (по спецификации), почему вы получаете false возвращается. Имейте в виду, что вполне возможно, что разные браузеры имеют разные реализации.

Как насчет этого?

doubleReturn();

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

  try {
    return sex;

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

    alert(sex);
  }
}