javascript
1let num = new Array(); 2for(let i=0;i<10;i++){ 3num[i] = increase(); 4} 5console.log(num); 6increase(){}
呼び出されるたびに戻り値が一ずつ増える関数をつくりたいんですが、どうすればつくれるのでしょうか?
グローバル変数を使えばできますが、グローバル変数を使わずにできるでしょうか?
上の例ではconsole.logで [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]が出力されるようにしたいんです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
こんにちは。
クロージャを使って、以下のように書けます。
javascript
1const increase = (x) => (() => x ++); 2 3const f = increase(1); 4 5let num = new Array(); 6for(let i = 0;i < 10;i ++) { 7 num[i] = f(); 8} 9 10console.log(num);
上記のコードにある f
は、 increase
の仮引数 x
への
参照を保持したクロージャであり、この f
がご質問のタイトルにある、
呼び出されるたびに戻り値が一ずつ増える関数
になっています。上記のコードを実行するとnum
の内容として
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
が出力されます。
補足 1
以下、ご質問の本題からやや外れるかもしれませんが、補足しますと、
ジェネレータを使って以下のような実現方法もあるかなと思いました。
javascript
1function* increaseGen(start, end) { 2 let n = start; 3 while ( n <= end ) 4 yield n ++; 5} 6 7const f = increaseGen(1, 10);
こうすると、f.next
が、ご質問のタイトルにある
呼び出されるたびに戻り値が一ずつ増える関数
に (近いものに) なります。
欲しい値(今の場合、1から始まり 10 まで1ずつ増える整数)は f.next()
が返す値
としてではなく、 f.next()
の返すオブジェクト(イテレータリザルトと呼ばれます。)の
value
プロパティとして得られます。
javascript
1console.log(f.next()); // => { value: 1, done: false } 2console.log(f.next()); // => { value: 2, done: false } 3console.log(f.next()); // => { value: 3, done: false } 4console.log(f.next()); // => { value: 4, done: false } 5console.log(f.next()); // => { value: 5, done: false } 6console.log(f.next()); // => { value: 6, done: false } 7console.log(f.next()); // => { value: 7, done: false } 8console.log(f.next()); // => { value: 8, done: false } 9console.log(f.next()); // => { value: 9, done: false } 10console.log(f.next()); // => { value: 10, done: false } 11console.log(f.next()); // => { value: undefined, done: true }
上記のような increaseGen
を作っておくことによって、for
ループを使わなくても
javascript
1let num = [...increaseGen(1,10)];
とするだけで、1から10までを要素に含む配列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
が
num
に入ります。
ジェネレータは何かと便利です。
補足 2
いろいろ脇道にそれてすみません。
1から10までの整数が要素として入っている配列を作って、let num
に入れることが
主目的なのであれば、以下のようにすると、クロージャもジェネレータも不要で、かつ、
for
ループも使わないで出来ます。
javascript
1let num = [...Array(10)].map((_ ,i) => i+1); 2 3console.log(num); // => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
または、
javascript
1let num = Array(10).fill(0).map((_ ,i) => i+1); 2 3console.log(num); // => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
以上参考になれば幸いです。
投稿2018/06/10 03:49
編集2018/06/24 14:22総合スコア9058
0
JavaScript
1const n = function () { return this.i++; }.bind({i:0}); 2console.log(n()); // 0 3console.log(n()); // 1 4console.log(n()); // 2 5console.log(n()); // 3
Re: liflect さん
投稿2018/06/10 03:49
編集2018/06/10 03:49総合スコア18189
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/06/10 21:27
2018/06/10 22:01