Why is ES6 “yield” a reserved word when called in this context?

前端 未结 5 2137
别跟我提以往
别跟我提以往 2020-12-09 09:34

I am using node 4.1.1. When I run this code

\"use strict\";

function *generator() {
  let numbers = [1,2,3,4,5];
  numbers.map(n => yield (n + 1));
}

f         


        
5条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-09 10:13

    You can do anything but not everything – Learn to delegate

    Let's first look at two examples

    1. yield

    function* generator(numbers) {
      yield numbers.map(x => x + 1);
    }
    
    for (let n of generator([1,2,3])) console.log(n);
    // [ 2, 3, 4 ]

    Our for loop logs each value yielded by the generator. Inside our generator, we have a single yield call which will yield the result of the numbers.map call, which is a new Array. Because there is only a single yield, the only logged value is [2,3,4]

    2. yield*

    So yield obviously won't work in the case above. We'll have to try something else.

    function* generator(numbers) {
      yield* numbers.map(x => x + 1);
    }
    
    for (let n of generator([1,2,3])) console.log(n);
    // 2
    // 3
    // 4

    Again, our for loop logs each value yielded by the generator. Inside our generator, we yield the same result of the numbers.map call, but this time we use yield*, which yield by delegation.

    What are we yielding then? Well, Array's have a built-in generator, Array.prototype[Symbol.iterator]. So at this point, the for loop is essentially directly stepping thru the generator provided by the Array. Since the array has 3 values, we see 3 logged values.


    Watchful eyes

    So we iterate thru numbers once using Array.prototype.map but then we iterate thru the intermediate array using the for loop? Seems like a waste doesn't it?

    Let's look back at your original code though

    function *generator() {
      let numbers = [1,2,3,4,5];
      numbers.map(n => yield (n + 1));
    }
    
    for (var n of generator()) {
      console.log(n);
    }
    

    Notice that your numbers.map call is pretty meaningless. Array.prototype.map creates a new array, but your generator doesn't do anything with it. So really you're just using map to iterate thru the numbers, not because you actually care about the returned value of map


    Say what you mean, mean what you say

    OK, so now we know we only really care about iterating thru the numbers. So we'll use iteration the way JavaScript knows best

    function* generator(numbers) {
      for (let x of numbers)
        yield x + 1
    }
    
    for (let n of generator([1,2,3])) console.log(n);
    // 2
    // 3
    // 4

    Bingo. No tricky yield*. No double iteration. No nonsense.

提交回复
热议问题