Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When using spread syntax on a generator why return value is not retrieved

I was expecting 4 to be part of the sequence array, so why is it skipped?

function* generate() {
  yield 1;
  yield 2;
  yield 3;
  return 4
}
let sequence = [...generate()];
console.log(sequence); // 1, 2, 3
like image 759
Mehdi Benmoha Avatar asked Jan 24 '21 13:01

Mehdi Benmoha


People also ask

What does spread syntax do?

Spread syntax ( ... ) allows an iterable, such as an array or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected.

What do generator functions return?

Regular functions return only one, single value (or nothing). Generators can return (“yield”) multiple values, one after another, on-demand. They work great with iterables, allowing to create data streams with ease.

Does spread operator pass reference?

Spread allows you to make a shallow copy of an array or object, meaning that any top level properties will be cloned, but nested objects will still be passed by reference.

How does the spread operator work?

The spread operator ( ... ) helps you expand iterables into individual elements. The spread syntax works within array literals, function calls, and initialized property objects to spread the values of iterable objects into separate items. So effectively, it does the opposite thing from the rest operator.


Video Answer


1 Answers

The return value of a generator function is not considered part of the sequence. It is returned from the last .next() call as {done: true, value:…}, where done: true implies that the sequence was completed and .next() should not be called again.

Why is that so, why couldn't we just yield the last value with the done flag set to true? Because then we could not represent an empty sequence with an iterator - the first .next() call would already lead to at least one value.1

So usually, generator functions do not return anything (but undefined), and all sequence values are yielded with the same syntax - there is no weird special syntax for the last value2:

function* generate() {
  yield 1;
  yield 2;
  yield 3;
  yield 4;
}

1: Other languages do this differently. There, iterators have a separate .hasNext() method that is called before .next(), or their .next() method either returns a value or throws a StopIteration exception. They don't have any "final value".
2: Having to know beforehand that a value is that last and using return instead of yield for it would make the logic for dynamically generated sequences much more complicated.

like image 50
Bergi Avatar answered Sep 22 '22 08:09

Bergi