Подтвердить что ты не робот

Какой тип ключевое слово 'return'?

Мы используем return заявления в функциях JavaScript. Это ключевое слово. Но каков фактический тип return. На самом деле я смутился, увидев пример:

function add(a, b) {
  return (
    console.log(a + b),
    console.log(arguments)
  );
}

add(2, 2);

Вывод:

4
[2, 2]

Итак, мы можем передавать выражения, разделенные запятыми, в оператор return. Является ли это функцией?

И начиная с этого, можем ли мы предположить, что каждое ключевое слово в JavaScript в конечном счете является функцией?

Я написал небольшой блог как суть этой дискуссии. Вы можете проверить его здесь.

4b9b3361

Ответ 1

Но каков фактический тип "возврата".

У него нет типа, это не значение.

Попытка typeof return; даст вам Unexpected token return.

Итак, мы можем передавать выражения, разделенные запятыми, в оператор return. Является ли это функцией?

Нет, в то время как скобки могут использоваться для вызова функции, здесь они представляют собой оператор группировки , содержащий пару выражений, разделенных символом оператор запятой.

Более полезной демонстрацией будет:

function add(a, b) {
  return (
    (a + b),
    (a - b)
  );
}

console.log(add(2, 2));

Какие выходы 0, потому что результат a + b игнорируется (он находится на LHS оператора запятой) и возвращается a - b.

Ответ 2

Я как бы шокирован тем, что никто здесь напрямую не ссылался на спецификацию:

12.9 Синтаксис утверждения возврата ReturnStatement: return; return [no LineTerminator here] Expression;

Семантика

Программа ECMAScript считается синтаксически неправильной, если она содержит оператор return, который не входит в FunctionBody. return возвращает функцию прекращения выполнения и возвращает значение для вызывающего. Если выражение не указано, возвращаемое значение равно undefined. В противном случае возвращаемое значение будет значением выражения.

Функция ReturnStatement оценивается следующим образом:

Если выражение отсутствует, верните (return, undefined, empty). Пусть exprRef является результатом оценки выражения. Верните (return, GetValue(exprRef), empty).

Итак, из-за спецификации ваш пример гласит:

return ( GetValue(exprRef) )

где exprRef = console.log(a + b), console.log(arguments)

Что соответствует спецификации для оператора запятой...

Семантика

Вывод Expression: Expression, AssignmentExpression оценивается следующим образом:

Let lref be the result of evaluating Expression.
Call GetValue(lref).
Let rref be the result of evaluating AssignmentExpression.
Return GetValue(rref).

... означает, что каждое выражение будет оцениваться до последнего элемента в списке запятой, который становится выражением присваивания. Таким образом, ваш код return (console.log(a + b) , console.log(arguments)) будет

1.) напечатать результат a + b

2.) Ничего не осталось для выполнения, поэтому выполните следующее выражение, которое

3.) печатает arguments, а потому, что console.log() не указывает return

4.) Вычисляет undefined

5.), который затем возвращается вызывающему.

Итак, правильный ответ: return не имеет типа, он возвращает результат некоторого выражения.

Для следующего вопроса:

Итак, мы можем передавать выражения, разделенные запятыми, в оператор return. Является ли это функцией?

Нет. Запятая в JavaScript является оператором, который позволяет объединять несколько выражений в одну строку и определяется спецификацией, чтобы возвращать вычисленное выражение того, что является последним в вашем списке.

Ты все еще не веришь мне?
<script>
alert(foo());
function foo(){
    var foo = undefined + undefined;
    console.log(foo);
    return undefined, console.log(1), 4;
}
</script>

Играйте с этим кодом здесь и беспорядок с последним значением в списке. Он всегда будет возвращать последнее значение в списке, в вашем случае это просто undefined.

За последний вопрос,

И начиная с этого, можно ли предположить, что каждое ключевое слово в JavaScript в конечном счете является функцией?

Опять же, нет. Функции имеют очень специфическое определение на языке. Я не буду перепечатывать его здесь, потому что этот ответ уже очень длинный.

Ответ 3

Проверка того, что происходит, когда вы возвращаете значения в скобках:

function foo() {
    return (1, 2);
}

console.log(foo());

Дает ответ 2, поэтому представляется, что список значений, разделенных запятыми, оценивается последним элементом в списке.

Действительно, скобки здесь неактуальны, они группируют операции вместо обозначения вызова функции. Что, возможно, удивительно, так это то, что запятая здесь законна. Я нашел интересное сообщение в блоге о том, как здесь запятая:

https://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/

Ответ 4

return не является функцией. Это продолжение функции, в которой оно происходит.

Подумайте о утверждении alert (2 * foo(bar));, где foo - имя функции. Когда вы оцениваете это, вы видите, что вам нужно отложить остальную часть инструкции на мгновение, чтобы сосредоточиться на оценке foo(bar). Вы могли бы визуализировать часть, которую вы отложили, как нечто вроде alert (2 * _), с заполнением пробела. Когда вы знаете, что такое значение foo(bar), вы забираете его снова.

То, что вы отложили, было продолжением вызова foo(bar).

Вызов return передает значение этому продолжению.

Когда вы оцениваете функцию внутри foo, остальная часть foo ждет, чтобы эта функция уменьшилась до значения, а затем foo снова забирает. У вас все еще есть цель оценить foo(bar), он просто остановился.

Когда вы оцениваете return внутри foo, никакая часть foo не ждет значения. return не сводится к значению в месте внутри foo, где вы его использовали. Вместо этого он приводит к тому, что весь вызов foo(bar) уменьшается до значения, а цель "оценить foo(bar)" считается полной и сдутой.

Люди обычно не говорят вам о продолжениях, когда вы новичок в программировании. Они думают об этом как о передовой теме, просто потому, что есть некоторые очень продвинутые вещи, которые люди в конечном итоге делают с продолжениями. Но, правда, вы используете их все время, каждый раз, когда вы вызываете функцию.

Ответ 5

return здесь находится красная селедка. Возможно, интересна следующая вариация:

function add(a, b) {
  return (
    console.log(a + b),
    console.log(arguments)
  );
}

console.log(add(2, 2));

который выводится как последняя строка

undefined

поскольку функция фактически ничего не возвращает. (Он вернет возвращаемое значение второго console.log, если оно есть).

Как бы то ни было, код точно идентичен

function add(a, b) {
    console.log(a + b);
    console.log(arguments);
}

console.log(add(2, 2));

Ответ 6

Интересный способ понять return с помощью Оператор void Взгляните на этот код

var console = {
    log: function(s) {
      document.getElementById("console").innerHTML += s + "<br/>"
    }
}

function funReturnUndefined(x,y) {
   return ( void(x+y) );
}

function funReturnResult(x,y) {
   return ( (x+y) );
}

console.log( funReturnUndefined(2,3) );
console.log( funReturnResult(2,3) );
<div id="console" />