Почему возврат в `finally` отменяет` try`? - PullRequest
76 голосов
/ 01 октября 2010

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

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

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

Ответы [ 8 ]

78 голосов
/ 01 октября 2010

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

Вы захотите изменить свой код так, чтобы он выглядел так:

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

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

33 голосов
/ 01 октября 2010

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

Производство TryStatement : try Block Finally оценивается следующим образом:

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

А из стр. 36:

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

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

12 голосов
/ 01 октября 2010

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

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

3 голосов
/ 01 октября 2010

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

function example() {
    try {
        return true;
    }
    catch {
        return false;
    }
}
1 голос
/ 01 октября 2010

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

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

0 голосов
/ 19 марта 2019

Блок finally переписывает try return return (образно говоря).

Просто хотел бы отметить, что если вы возвращаете что-то из finally, то оно будет возвращено из функции.Но если в, наконец, нет слова 'return' - ему будет возвращено значение из блока try;

function example() {
    try {
        return true;
    }
    finally {
       console.log('finally')
    }
}
console.log(example());
// -> finally
// -> true

Так -finally- return переписывает возвращение -try- return.

0 голосов
/ 28 июня 2018

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

doubleReturn();

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

  try {
    return sex;

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

    alert(sex);
  }
}
0 голосов
/ 01 октября 2010

Наконец, ВСЕГДА должен запускаться в конце блока try catch, так что (по спецификации) вы получаете возвращаемое значение false. Помните, что вполне возможно, что разные браузеры имеют разные реализации.

...