21.8 代码风格:空格在星号之前还是之后

合理的并且合法的放置星号的方式是:

  • 星号两边保留空格:
function * foo(x, y) { ··· }
  • 星号之前保留空格:
function *foo(x, y) { ··· }
  • 星号之后保留空格:
function* foo(x, y) { ··· }
  • 星号前后都没有空格:
function*foo(x, y) { ··· }

让我们指出哪种形式对于哪种解构来说是合理的,并且解释为什么。

21.8.1 生成器函数的声明和表达式

此处,使用星号的原因是因为 generator (或者其它类似的单词)没有被用作关键字。如果可以作为关键字的话,那么生成器函数的声明就像这样子:

generator foo(x, y) {
    ···
}

ECMAScript 6 使用星号标记的 function 关键字来代替 generator 。因此, function* 可以看做是 generator 的同义词,这使得生成器函数声明的推荐写法就像下面这样。

function* foo(x, y) {
    ···
}

匿名生成器函数表达式的格式就像这样:

const foo = function* (x, y) {
    ···
}

21.8.2 生成器方法定义

当书写生成器方法定义的时候,我推荐如下的格式:

let obj = {
    * generatorMethod(x, y) {
        ···
    }
};

关于在星号之后放一个空格,有三个理由。

首先,星号不应该是方法名的一部分。一方面,它不是生成器函数名字的一部分。另一方面,仅在定义生成器的时候才会涉及到星号,在使用的时候并不会涉及到。

第二点,生成器方法定义是如下语法的缩写。(为了展现我的观点,我给函数表达式添加了多余的名字。)

let obj = {
    generatorMethod: function* generatorMethod(x, y) {
        ···
    }
};

如果方法定义要省略 function 关键字,那么星号后面就应该跟一个空格。

第三点,生成器方法定义在语法上类似于 getterssetters (这两个语法在 ECMAScript 5 中就可用了):

let obj = {
    get foo() {
        ···
    }
    set foo(value) {
        ···
    }
};

关键字 getset 可以看做普通方法定义的修饰器。同理,星号也是这样的一个修饰器。

21.8.3 用于嵌套调用的 yield 的书写格式

下面是一个 生成器函数通过 yield 递归调用自身的例子:

function* foo(x) {
    ···
    yield* foo(x - 1);
    ···
}

星号标记出不一样的 yield 操作符,这就是为什么上面的代码是合理的的原因。

21.8.4 标记生成器函数和方法

Kyle Simpson ( @getify )提出了有趣的看法:在函数或方法调用的时候,我们经常会在后面加上括号,例如 Math.max() ,而对于生成器函数和方法而言,在前面加上星号不是更合理吗?例如:在上一子节我们不应该写成 *foo() 来表明是一个生成器的调用吗?让我来驳斥这个观点。

当需要调用一个返回可迭代对象的函数的时候,生成器是几个可选项中唯一的一个。我认为最好不要抛弃这种标记函数名的实现细节。

而且,在调用生成器函数的时候,你不会使用星号,但是使用了括号。

最后,星号并不会提供有用的信息 - yield* 也可用于返回可迭代对象的函数。但是标记返回可迭代对象的函数或方法名(包括生成器)可能是合理的。例如,加上 Iter 前缀。

results matching ""

    No results matching ""