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

Почему функции JavaScript всегда возвращают значение?

Я изучаю курс программирования JavaScript, и инструктор сказал, что типичная функция JavaScript всегда возвращает значение. Даже когда мы не предоставляем никакого явного возвращаемого значения, двигатели возвращают undefined.

Это правда? Если да, то почему?

4b9b3361

Ответ 1

Это правда, потому что именно так был разработан JavaScript.

Но я не думаю, что ответ, который вы искали, так что подумайте об этом...
Попробуйте поставить себя на место Brendan Eich, человека, который разработал JavaScript!

В статических языках обычно существует различие между функцией, которая не return ничего (void) и функцию, возвращающую некоторое значение. Брендан выбрал язык динамический, то есть язык, который не требует определения типов возвращаемых функций. Поэтому JavaScript не проверяет, что вы возвращаете из функции, предоставляя вам полную свободу.

У вас может быть функция, которая возвращает число...

function computeSomething() {
  return 2;
}

... или строка...

function computeSomething() {
  return 'hi';
}

... или, фактически, любой из них:

function computeSomething() {
  if (Math.random() > 0.5) {
    return 2;
  } else {
    return 'hello';
  }
}

Иногда вам не нужно ничего вычислять - вам нужно всего лишь сделать.
Поэтому вы ничего не возвращаете.

function doSomething() {
   console.log('doing something');
}

Мы можем, однако, хотеть выйти из функции в середине ее, и поскольку return <value> уже делает именно это, имеет смысл разрешить запись return без значения для поддержки этого прецедента:

function doSomething(num) {
   if (num === 42) {
     return;
   }

   while (true) {
     doSomethingElse();
   }
}

Это также согласуется с синтаксисом C/Java, который был одной из целей обеспечения принятия JavaScript.

Да, там rub: что произойдет, если мы поместим простой return в функцию, которая должна что-то вычислить? Обратите внимание, что мы не можем запретить это: одно из наших предыдущих решений заключалось в том, чтобы сделать JavaScript динамическим языком, где мы не проверяем, что возвращает функция.

function computeSomething(num) {
  if (num === 42) {
    return; // just return? o_O
  }

  if (Math.random() > 0.5) {
    return 2;
  } else {
    return 'hello';
  }
}

var x = computeSomething(2); // might be 2, might be 'hello'
var y = computeSomething(42); // ???

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

Таким образом, пустой return получил значение "return undefined".

Но какая разница между функцией, возвращающейся рано или в конце? Их не должно быть, с кодовой точки зрения. Код вызова не должен знать, когда именно возвращаемая функция; его интересует только возвращаемое значение (если оно есть).

Единственным логическим заключением, таким образом, было бы сделать undefined возвращаемое значение "по умолчанию", если функция не указывает один через явный оператор return <value>. Таким образом, соответствие return и семантика, выполняемая по функциям, и .

Python, еще один динамический язык, который появился перед JavaScript, решает эту проблему одинаково: None возвращается, если функция не указывает возвращаемое значение.

Ответ 2

Это спецификация ECMAScript

13.2.1 [[Call]]... 6. В противном случае result.type должен быть нормальным. Верните undefined.

По сути, любая JS-функция компилируется так, как будто она имеет неявный return undefined; в конце:

function foo() {
  ...

  return undefined; // implicit non-visible statement  
}

Ответ 3

Даже когда мы не предоставляем никакого явного возвращаемого значения, двигатели возвращают "undefined". Это правда?

Не совсем. Насколько я понимаю, функция, которая ничего не возвращает... ничего не возвращает. Тем не менее, если вы назначаете переменную на результат такого вызова функции, выражение будет оцениваться как undefined.Забастовкa >

ИЗМЕНИТЬ

Я стою исправлено. Здесь соответствующая часть спецификации:


13.2.1 [[Call]]

Когда вызывается внутренний метод [[Call]] для объекта функции F с этим значением и списком аргументов, выполняются следующие шаги:

  • Пусть funcCtx является результатом создания нового контекста выполнения для кода функции с использованием значения внутреннего свойства F [[FormalParameters]], переданных аргументов List args и этого значения, как описано в 10.4.3.
  • Пусть результат будет результатом оценки FunctionBody, являющегося значением внутреннего свойства F [[Code]]. Если F не имеет внутреннего свойства [[Code]] или если его значение является пустым FunctionBody, тогда результат будет (normal, undefined, empty).
  • Закройте контекст выполнения funcCtx, восстановив предыдущий контекст выполнения.
  • Если result.type - это throw, то throw result.value.
  • Если result.type является возвратом, тогда возвращаем result.value.
  • В противном случае result.type должен быть нормальным. Верните undefined.

Ответ 4

В javascript функции - это объекты. Поэтому вы всегда можете назначить функцию переменной, как если бы вы назначили какой-либо другой объект, и интерпретатор заставит определить значение (которое может быть undefined.)