質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

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

Q&A

解決済

2回答

2095閲覧

returnでfunctionを返す挙動

gaisei

総合スコア12

JavaScript

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

0グッド

1クリップ

投稿2017/05/01 09:20

編集2017/05/01 09:22

とある参考書にてJavaScriptの勉強をしているうちに、どのどうな挙動をしているのかわからなくなってしまったので質問させてください。

スクリプトは以下の通りです。
※長くて申し訳ありません

JavaScript

1function Modal(el) { 2 this.initialize(el); 3} 4 5Modal.prototype.initialize = function(el) { 6 this.$el = el; 7 this.$container = $("#modal"); 8 this.$contents = $("#modal-contents"); 9 this.$close = $("#modal-close"); 10 this.$next = $("#modal-next"); 11 this.$prev = $("#modal-prev"); 12 this.$overlay = $("#modal-overlay"); 13 this.$window = $(window); 14 this.handleEvents(); 15}; 16 17Modal.prototype.handleEvents = function() { 18 var self = this; 19 this.$el.on("click", function(e) { 20 self.show(e); 21 return false; 22 }); 23 24 this.$overlay.on("click", function(e) { 25 self.hide(e); 26 return false; 27 }); 28 29 this.$close.on("click", function(e) { 30 self.hide(e); 31 return false; 32 }); 33 34 this.$next.on("click", function(e) { 35 self.next(e); 36 return false; 37 }); 38 39 this.$prev.on("click", function(e) { 40 self.prev(e); 41 return false; 42 }); 43}; 44 45Modal.prototype.show = function(e) { 46 var $target = $(e.currentTarget), 47 src = $target.attr("href"); 48 this.$contents.html("<img src=\"" + src + "\" />"); 49 this.$container.fadeIn(); 50 this.$overlay.fadeIn(); 51 var index = $target.data("index"); 52 this.countChange = this.createCounter(index, this.$el.length); // ① 53 return false; 54}; 55 56Modal.prototype.hide = function(e) { 57 this.$container.fadeOut(); 58 this.$overlay.fadeOut(); 59}; 60 61Modal.prototype.slide = function(index) { 62 this.$contents.find("img").fadeOut({ 63 complete: function() { 64 var src = $("[data-index=\"" + index + "\"]").find("img").attr("src"); 65 $(this).attr("src", src).fadeIn(); 66 } 67 }); 68}; 69 70// ② 71Modal.prototype.countChange = function(num, index, len) { 72 return (index + num + len) % len; 73}; 74 75// ③ 76Modal.prototype.createCounter = function(index, len) { 77 return function(num) { 78 return index = (index + num + len) % len; 79 }; 80}; 81 82Modal.prototype.next = function() { 83 this.slide(this.countChange(1)); 84}; 85 86Modal.prototype.prev = function() { 87 this.slide(this.countChange(-1)); 88}; 89 90var modal = new Modal($("#modal-thumb a"));

これはモーダルとして正常に機能するのですが、
画像をタップするとshow関数が呼ばれて①から③が動くのですが、この時点では

javascript

1return function(num) { 2 return index = (index + num + len) % len; 3};

の引数のnumはわたってきていません。
next、prevボタンが押されると、それぞれnext,prev関数が機能してnumに1か-1が渡ってきます。

わからないのが、
まず③でreturnでfunctionしている意味、また、単に

javascript

1return index = (index + num + len) % len;

だけではいけない理由。

それと、①で

javascript

1this.countChange = this.createCounter(index, this.$el.length)

としているなかで、どのタイミングでnumが渡っていくのか。

自分的に理解が及ばず質問が抽象的になってしまっており申し訳ありませんが、
ご教示いただけたら幸いです。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

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

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

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

guest

回答2

0

ベストアンサー

これはクロージャを使ったカウンタですね。
簡単にしたコードをしめします。

javascript

1function createCounter(x){ 2 return function(y){ return x = x + y } 3} 4var counter = createCounter(0); 5counter(1); // 0+1=1 6counter(1); // 1+1=2 クロージャが前回の1を記憶している 7counter(10); // 2+10=12 8counter(-1); // 12+-1=11 9 10var counter2 = createCounter(10); 11counter2(5); // 10+5=15 counterとは別の数字を記憶する。 12counter(100); // 11+100=111 13counter2(5); // 15+5=20 14 15createCounter(0)(100); // 100 16createCounter(0)(100); // 100 この場合は返り値の関数の参照を持っていないので、クロージャにアクセスできない。 17

以上を踏まえまして、回答します。

まず③でreturnでfunctionしている意味

クロージャを作成するために関数を返す必要があります。

どのタイミングでnumが渡っていくのか。

↓ここです。

javascript

1this.countChange(1)

投稿2017/05/01 11:24

Lhankor_Mhy

総合スコア35865

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

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

0

this.countChangeは、たぶん、カウントが変わった時に実行される関数ですね。
だから、

return index = (index + num + len) % len;

として、単に数値を返すと、カウントが変わってもここで計算された数値のままになります。

カウントが変わった時に計算する関数そのものを返しているのが

Modal.prototype.createCounter = function(index, len) { return function(num) { return index = (index + num + len) % len; }; };

です。

投稿2017/05/01 09:50

yoorwm

総合スコア1305

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問