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

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

新規登録して質問してみよう
ただいま回答率
85.50%
プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

JavaScript

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

Q&A

解決済

2回答

1917閲覧

ソースの流れに公理はあるのか

aaaaaaaa

総合スコア501

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

JavaScript

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

0グッド

0クリップ

投稿2017/08/25 10:41

編集2017/08/28 10:30

下記のソースは、初歩的なモーダルウィンドウが記述されたものです。
ソースの流れとして

function Modal(el) { this.initialize(el); } Modal.prototype.initialize = function(el) {//initialize…初期化する this.$el = el; this.$container = $("#modal"); this.$contents = $("#modal-contents"); this.$close = $("#modal-close"); this.$next = $("#modal-next"); this.$prev = $("#modal-prev"); this.$overlay = $("#modal-overlay"); this.$parents = this.$el.parents("ul"); this.$window = $(window); this.handleEvents(); }; Modal.prototype.handleEvents = function() { var self = this; this.$parents.on("click","a", function(e) { self.show(e); return false; }); this.$close.on("click",function(e) { self.hide(e); return false; }); this.$overlay.on("click",function(e) { self.hide(e); return false; }); this.$next.on("click", function(e) { self.next(e); return false; }); this.$prev.on("click", function(e) { self.prev(e); return false; }); this.$window.on("load resize", function() { self.resize(); }); }; Modal.prototype.show = function(e) { var $target = $(e.currentTarget), src=$target.attr("href"); this.$contents.html("<img src=\"" + src +"\"/>"); this.$container.fadeIn(); this.$overlay.fadeIn(); var index = $target.data("index"); this.countChange = this.createCounter(index,this.$el.length); return false; }; Modal.prototype.hide = function(e) { this.$container.fadeOut(); this.$overlay.fadeOut(); }; Modal.prototype.slide = function(index) { this.$contents.find("img").fadeOut({ complete: function() { var src = $("[data-index=\"" + index + "\"]").find("img").attr("src"); $(this).attr("src",src).fadeIn(); } }); }; Modal.prototype.createCounter = function(index, len) { return function(num) { return index = (index + num + len) % len; }; }; Modal.prototype.next = function() { this.slide(this.countChange( 1 )); }; Modal.prototype.prev = function() { this.slide(this.countChange( -1 )); }; Modal.prototype.resize = function() { var w = this.$window.width(); if(w<640) { this.$container.css({"width":"320","height":"213"}); } else { this.$container.css({"width":"750","height":"500"}); } }; $("#more-btn").on("click", function() { var html = "<li><a href=\"photo-04.jpg\" data-index=\"3\"><img alt=\"\" src=\"photo-04.jpg\" width=\"160\" class=\"img-thumbnail\"></a></li>"; $(html).appendTo($("#modal-thumb")).hide().fadeIn(); $(this).fadeOut(); modal.$el = $("#modal-thumb a"); }); var modal = new Modal($("#modal-thumb a"));

Modalが実体化されるとプロトタイプオブジェクトプロパティinitializeのメソッドinitialize()が実行され、さらにinitialize()内でプロパティの初期化をおえるとhandleEventsが実行されます。
しかし、イベントが発生しないと何も始まらないので待機します。そしてModalを実体化したときに渡した実引数$("#modal-thumb a")や、initialize内で初期化したjqueryオブジェクトに渡したセレクタなどがクリックされたら、同じくModalのプロトタイプであるshowメソッドやhideメソッドなどにイベントオブジェクトを実引数として渡したうえで実行する、という流れになっております。

ここで質問です。このソース最下部で実体化したコンストラクタModalからinitializeを実行しさらにinitialize()内でプロパティの初期化をおえるとhandleEventsが実行されますが、イベントが発生しないと何も始まらないので待機します。
そしてModalを実体化したときに渡した実引数$("#modal-thumb a")や、initialize内で初期化したjqueryオブジェクトに渡したセレクタなどがクリックされたら、同じくModalのプロトタイプであるshowメソッドやhideメソッドなどにイベントオブジェクトを実引数として渡したうえで実行する、という流れですが、このソースの流れはjavascriptにおける公理(一種の決まりのようなもの)なのでしょうか。
つまりvarのように絶対付けないといけないわけではないが、付けないと後々に不具合のもととなるので任意で付けているように何かしらソースを構築する上でここにあれを、それをあそこにというような決まった、或いはそうしたほうがいいよね、というソースの流れがあるのでしょうか。このソースもそのような流れの公理があってそのようにしているのでしょうか。

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

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

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

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

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

Lhankor_Mhy

2017/08/26 02:29

ご質問は、initializeメソッドやhandleEventsメソッドを、prototypeプロパティ下に置いているのはなぜか、ということですか?
aaaaaaaa

2017/08/28 10:30

ご返答ありがとうございます。仰る通りです。質問文を見返しましたが、かなり分かりづらいものとなっておりましたので修正しました。
guest

回答2

0

ベストアンサー

このソースの流れはjavascriptにおける公理(一種の決まりのようなもの)なのでしょうか

こういう考え方は好ましくない、と私は思っています。
この手の話題では https://okwave.jp/qa/q5081024.html のKI401さんの言葉を思い出します。

別に法律で規制されてるわけでもなし、使用しては「いけない」ことはないと思う。
単に、普通ならこんな汚染ライブラリ使いたくないよね?ってだけのハナシ。

じゃ「使いたくない」って、それはなぜか?

保守性が悪くなるからだ。
バグの原因になるからだ。

重要なのは、「なぜそのコードが推奨/非推奨なのか」を理解していることです。
極論をいえば、仕組みが分かっていれば何を使っても良いのです。
仕組みが分かっている人は、良いコードを自分で考えて導き出すでしょう。
そういう人は「公理だから」という理由ではなく、「~という理屈から保守性が高くなるから」のような理由でコードの書き方を選択します。

初心者向けに「理屈はいいからこういうコードを書け」と教えることもあると思いますが、それは初めだけで、いずれは理屈も理解して貰わなければ困ります。

長くなりましたが、答えを書きます。
Modalからinitializeを実行するのは公理ではありません。
この書き方は後で initialize() を実行し直す事で初期化をやり直せることを意図したものですが、インスタンスから作り直しても良いので、この書き方に拘る必要はありません。
そもそも、this.$el しか初期化し直さないのなら、直接書き換えても同じです。

Re: aaaaaaaa さん

投稿2017/08/26 08:56

think49

総合スコア18156

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

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

aaaaaaaa

2017/08/28 10:32

ご回答ありがとうございます。 つまりソースの流れに着目するよりも、記述しているソースが今現在使われるべきものなのか、使われないべきなのかに着目すべきであるということですね。
think49

2017/08/28 12:22

そうですね。 コードの書き方が複数存在した場合、自分が書くコードの目的によりマッチしている方を選択すべき、ということだと思います。 今回の例でいえば、インスタンスの初期化をやり直すなら使うべきですし、やり直さないなら使うべきではありません。 では、「そもそも、初期化をやり直す必要があるのか」と突き詰めて考えていくわけです。
aaaaaaaa

2017/08/29 10:43

ご返答ありがとうございました。 >>この書き方は後で initialize() を実行し直す事で初期化をやり直せることを意図したものですが、 質問文には、表記し忘れておりましたがこのソースは、勉学用の書籍で作ったものです。しかし、書籍には initializeを実行し直すことで…という内容は書いておりませんでしたので、なるほどと思いました。 つまりinitialize()で初期化したプロパティたちが、何らかの処理で別の値を代入されてもinitialize()を再度実行すれば 元に戻る(最初に初期化したときの値が代入される)、ということを狙った、というか想定したソースだということですよね。
think49

2017/08/29 14:27 編集

> 書籍には initializeを実行し直すことで…という内容は書いておりませんでしたので、なるほどと思いました。 多分、考え方の問題になるのだと思います。 書籍に全て書いてある事はおそらくありませんが、「自分が書く場合ならどうだろう」「この書き方と他の書き方を比較検討してみたら、各々の長所/短所は何だろう」とシミュレーションしてみる事で見えてくるものはあります。 > つまりinitialize()で初期化したプロパティたちが、何らかの処理で別の値を代入されてもinitialize()を再度実行すれば元に戻る(最初に初期化したときの値が代入される)、ということを狙った なるほど、「元に戻る」という発想が私にはありませんでした。 その考え方でいく場合、問題となるのは Modal.prototype.handleEvents の処理です。 jQuery#on では新しい関数オブジェクトを指定している為、handleEvents() が呼び出される度に新しいイベントハンドラが定義される事になります。 var modal = new Modal($("#modal-thumb a")); modal.initialize($("#modal-thumb a")); このコードによって各イベントハンドラは2回ずつ発動されることになり、意図しない動作となります。 期待通りにリセットする為には各々のイベントハンドラを jQuery#off で削除してから initialize() を呼び出す必要があります。 イベントハンドラ周りの再初期化が考えられているコードではないと思います。 個人的な感想としては良い出来のコードとはいえないので、Lhankor_Mhy さんが仰るように、コンストラクタパターンの一つとして読み、細かな書き方はご自身でいろんなパターンのコードを書いて試していく事をお勧めします。 aaaaaaaa さんは書籍を引用した質問をよくしていますが、自分で書いたコードの質問があまりないので、実際に書いた経験が少ないのではと感じています。 全てが分からなくてもいいのでご自身で書いてみる事は良い経験になると思います。
aaaaaaaa

2017/08/30 10:42

ご返答ありがとうございました。大変助かりました。 確かに書籍に頼りすぎるのではなく自分の頭を動かして記述することも大事ですね。phpは、だいぶそうなってきました。javascriptはまだまだ書籍の助けも必要ですが、貴重なご意見の通りにやってみようかなとも思います。
guest

0

おそらく、公理とは「デザインパターン」のことを言ってるのだと思います。
この書き方は、javascriptにおける「コンストラクタパターン」の標準的な書き方に沿っているかと思います。
「JavaScriptデザインパターン コンストラクタパターン」でググってみるといいのでは。

JavaScriptのパターン コンストラクタパターン - @ledsun blog
ステップアップのためのJavascriptデザインパターン入門(2) - コンストラクタパターン - イソップブログ
JavaScript のクラス定義

投稿2017/08/28 06:40

Lhankor_Mhy

総合スコア35871

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

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

Lhankor_Mhy

2017/08/28 06:57

よく見ると、3つ目のリンク先のコードはよくないですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問