56052


いつもお世話になっています。  
下記の質問についてご存知の方がいらっしゃいましたらご教示を願います。

* * *

## 【質問の主旨】

[GitHub](https://github.com/echizenyayota/ch6/blob/master/scripts/class_iterator.js#L2)で公開したJavaScriptのコードには、`constructor(...values)
{` という記述があります。このうち`...`の部分は何を示すのでしょうか？

## 【質問の補足】

### 1.

`...`について[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes/constructor#Default_constructors)で確認すると以下のように説明されています。

> 派生クラスの既定のコンストラクタは次のようになります

この「派生クラスの既定のコンストラクタ」とは何を意味するのかよく分かりません。

### 2.

上記のGitHubのコードを実行して、コンソール画面を確認すると、以下の結果が表示されます。

  * `constructor(...values) {` の場合

[code]

    panda
    dog
    rabbit
    
[/code]

  * `constructor(values) {` の場合

[code]

    p
    a
    n
    d
    a
    
[/code]

ですがなぜ出力結果が異なるのか理由はよく分かりません。

### 3.

今回の質問は「JavaScript逆引きレシピ 第2版」のP249より引用しています。  
<https://www.shoeisha.co.jp/book/detail/9784798157573>

* * *

以上、ご確認のほどよろしくお願い申し上げます。


CC BY-SA 4.0
2019-06-24T00:55:20.480
56041
2019-06-24T03:03:49.933
32232
question
javascript
"constructor(...values) {" という表現のうち "..." の意味を教えてください


> GitHubで公開したJavaScriptのコードには、constructor(...values) {
> という記述があります。このうち...の部分は何を示すのでしょうか？

[Rest
parameters](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/rest_parameters)
です。

* * *

> 「派生クラスの既定のコンストラクタ」とは何を意味するのかよく分かりません。

「基本クラスを継承したクラス(派生クラス)のコンストラクタ」を指します。

つまり、継承をしたうえでコンストラクタを用意していない場合、以下のようなコンストラクタが自動で用意されるということになります[[1]](https://www.ecma-
international.org/ecma-262/9.0/#sec-runtime-semantics-
classdefinitionevaluation)。

[code]

    constructor(...args) {
      super(...args);
    }
    
[/code]

> # 14.6.13 Runtime Semantics:
> ClassDefinitionEvaluation[[1]](https://www.ecma-
> international.org/ecma-262/9.0/#sec-runtime-semantics-
> classdefinitionevaluation)
>
>   10. If constructor is empty, then
>     1. If ClassHeritageopt is present, then
>       1. Set constructor to the result of parsing the source text
[code]>             constructor(... args){ super (...args);}

>  
[/code]

>
> using the syntactic grammar with the goal symbol MethodDefinition[~Yield,
> ~Await].
>     2. Else,
>       1. Set constructor to the result of parsing the source text
[code]>             constructor(){ }

>  
[/code]

>
> using the syntactic grammar with the goal symbol MethodDefinition[~Yield,
> ~Await].
>

* * *

> なぜ出力結果が異なるのか理由はよく分かりません。

Rest parameters によって、引数を配列として受け取ることが出来ます。

例えば、以下の関数を実行した結果、関数 `hoge` は引数を要素とした配列を返します。

[code]

    function hoge(...args) {
      return args;
    }
    
    console.log(hoge(1, 2, 3)); //=> Array [1, 2, 3]
    
    
[/code]

質問文のコードであれば、`MyArray` クラスのコンストラクタに渡された引数すべてを配列化し、`values`
プロパティに代入していることになります。その結果、`values` プロパティの各要素の内容が出力されます。

[code]

    class MyArray {
        constructor(...values) {
            this.values = values;
            console.log(this.values); //=> Array(3) [ "panda", "dog", "rabbit" ]
        }
    
        [Symbol.iterator]() {
            let i = 0;
            let that = this;
            return {
                next() {
                    return i < that.values.length ?
                    { done: false, value: that.values[i++]} :
                    { done: true};
                }
            };
        }
    }
    
    let animals = new MyArray('panda', 'dog', 'rabbit');
    for (let animal of animals) {
        console.log(animal); //=> panda -> dog -> rabbit
    }
    
[/code]

もしここで、Rest parameters を使用しなかった場合、`MyArray` クラスのコンストラクタは、
**渡された最初の引数のみを`values` として受け取ります**。文字列は iterable であるため、最初に渡されている panda
という文字列が文字に分解されて出力されます。

[code]

    class MyArray {
        constructor(values) {
            this.values = values;
            console.log(this.values); //=> panda       
        }
    
        [Symbol.iterator]() {
            let i = 0;
            let that = this;
            return {
                next() {
                    return i < that.values.length ?
                    { done: false, value: that.values[i++]} :
                    { done: true};
                }
            };
        }
    }
    
    let animals = new MyArray('panda', 'dog', 'rabbit');
    for (let animal of animals) {
        console.log(animal); //=> p -> a -> n -> d -> a
    }
    
[/code]


CC BY-SA 4.0
2019-06-24T03:03:49.933
56052
2019-06-24T03:03:49.933
32986
56041
answer