🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

5535閲覧

呼び出されるたびに戻り値が一ずつ増える関数をつくりたいんですが?

liflect

総合スコア14

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2018/06/10 03:31

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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

liflect

2018/06/10 21:27

いろいろな方法を教えてくれてありがとうございました。
jun68ykt

2018/06/10 22:01

解決されたようですね、良かったです!
guest

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
think49

総合スコア18189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

liflect

2018/06/10 21:28

短くてわかりやすいですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問