为什么在这种情况下调用ES6会“产生”一个保留字?

时间:2015-10-24 09:48:03

标签: javascript node.js ecmascript-6

我正在使用节点4.1.1。当我运行此代码时

"use strict";

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

for (var n of generator()) {
  console.log(n);
}

我收到此错误

  numbers.map(n => yield (n + 1));
                   ^^^^^

SyntaxError: Unexpected strict mode reserved word

如果我将代码重新排列为此

"use strict";

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

for (var n of generator()) {
  console.log(n);
}

我得到了预期的结果。

为什么第二个工作,第一个失败?当然,如果保留一个关键字,它会在所有上下文中保留,而不仅仅是在箭头函数中使用它?

5 个答案:

答案 0 :(得分:13)

您可以做任何事情,但不能做任何事情 - 学会委派

让我们先来看两个例子

<强> 1。产量

&#13;
&#13;
function* generator(numbers) {
  yield numbers.map(x => x + 1);
}

for (let n of generator([1,2,3])) console.log(n);
// [ 2, 3, 4 ]
&#13;
&#13;
&#13;

我们的for循环记录生成器产生的每个值。在我们的生成器中,我们有一个yield调用,它将产生numbers.map调用的结果,这是一个新的数组。由于只有一个产量,因此唯一记录的值为[2,3,4]

<强> 2。 yield*

所以yield显然不会在上面的案例中工作。我们必须尝试别的东西。

&#13;
&#13;
function* generator(numbers) {
  yield* numbers.map(x => x + 1);
}

for (let n of generator([1,2,3])) console.log(n);
// 2
// 3
// 4
&#13;
&#13;
&#13;

同样,我们的for循环记录了生成器编辑的每个值yield。在我们的生成器中,我们得到numbers.map调用的相同结果,但这次我们使用yield*,它由委托产生。

那我们有什么收益呢?那么,Array有一个内置的生成器Array.prototype[Symbol.iterator]。所以在这一点上,for循环基本上直接通过Array提供的生成器步进。由于数组有3个值,我们看到3个记录值。

注视

所以我们使用numbers一次迭代Array.prototype.map但是我们使用for循环通过中间数组进行迭代?看起来像废物不是吗?

让我们回顾一下你的原始代码

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

for (var n of generator()) {
  console.log(n);
}

请注意,您的numbers.map电话毫无意义。 Array.prototype.map会创建一个新数组,但您的生成器不会 对其进行任何操作。所以真的你只是使用map来迭代这些数字,而不是因为你真的关心map的返回值

说出你的意思,意思是你说的话

好的,现在我们知道我们只关心通过数字进行迭代。因此,我们将按照JavaScript最了解的方式使用迭代

&#13;
&#13;
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
&#13;
&#13;
&#13;

宾果。没有棘手yield*。没有双重迭代。没有废话。

答案 1 :(得分:12)

这是因为箭头功能不是发电机功能。例如,

function temp() {
  yield 1;
}

我们能指望这个吗?不。因为temp不是生成器函数。这同样适用于箭头功能。

FWIW,根据ECMAScript 2015规范,在箭头函数中使用yield是一个早期错误,根据this section

  

ArrowFunction:ArrowParameters =&gt; ConciseBody

     
      
  • 如果 ArrowParameters 包含 YieldExpression true ,则语法错误。

  •   
  • 如果 ConciseBody 包含 YieldExpression true ,则语法错误。

  •   

答案 2 :(得分:4)

那是因为箭头功能不是发电机。如果我扩展你的箭头功能,它看起来像:

$(document).ready(function () {
    $("#submit").click(function () {
        var radio1 = $("input[name=group1]:checked").val();
        var radio2 = $("input[name=group2]:checked").val();
        var radio3 = $("input[name=group3]:checked").val();
        var radio4 = $("input[name=group4]:checked").val();
        // Returns successful data submission message when the entered information is stored in database.
        var dataString = '&submit1=' + radio1 + '&submit2=' + radio2 + '&submit3=' + radio3 + '&submit4=' + radio4;

        if (radio1 == '' || radio2 == '' || radio3 == '' || radio4 == '') {
            alert("Please Fill All Fields");
        } else {
            // AJAX Code To Submit Form.
            $.ajax({
                type: "POST",
                url: "ajaxsubmit.php",
                data: dataString,
                cache: false,
                success: function (result) {
                    alert(result);
                }
            });
        }
        return false;
    });
});

答案 3 :(得分:1)

[1,2,3,4,5].map(function*(v){yield v+1;}).reduce((accumulator, currentValue) => accumulator = [...accumulator].concat([...currentValue]))

...解释

[1,2,3,4,5].map(function*(v){yield v+1;})

将所有值打包到生成器中

  

(5)[发电机,发电机,发电机,发电机,发电机]

解压缩到平面阵列

.reduce((accumulator, currentValue) => accumulator = [...accumulator].concat([...currentValue]))
  

(5)[2,3,4,5,6]

正常使用

[1,2,3,4,5].map(function*(v){yield v+1;}).forEach(v => console.log([...v][0]))
  

2

     

3

     

4

     

5

     

6

[... v] [0]有点难看,但它确实有效。

答案 4 :(得分:0)

刚发现你可能会因为过早关闭你的功能而遇到这种情况。

即。太多<Prompt>