すいません!javascriptを学び始めのものなのですが、以下のjavascriptコードを一行一行説明して頂けないでしょうか??
急ぎでjavascriptでコーディング出来るようになる必要があり、かなり焦ってます(汗)今日にはコーディングスタートしないといけない状況でやばいです。。。
全部でなくても勿論構いませんので、可能な範囲でお願い出来ると大変助かります!!
自分でも随時、わかるところ、わかったところはコメントを付けてみます。
※「投稿内容は3000文字以内で入力してください。」と表示されてしまったので、自分でわかったところや分かった気がするようなところはコメント欄に書き込んで行きますm(_ _)m
.
.
(function(exports) {
var TodoModel = function() {
this.contents = ’’;
this.listeners = [];
}
.
.
TodoModel.prototype.setContents = function(contents) {
if (this.contents !== contents) {
this.contents = contents;
this.notifyListeners();
}
}
.
.
TodoModel.prototype.bindToInput = function(input) {
var _this = this;
var eventHandler = function(e) {
if (typeof(e.target.value) != ’undefined’) {
_this.setContents(e.target.value);
}
};
input.addEventListener(’keyup’, eventHandler);
input.addEventListener(’change’, eventHandler);
}
.
.
TodoModel.prototype.bindToView = function(view) {
this.addListener(function(model) {
if (view.setValue) {
view.setValue(model.contents);
} else {
view.innerText=model.contents;
}
});
}
.
.
TodoModel.prototype.addListener = function(listener) {
this.listeners.push(listener);
}
.
.
TodoModel.prototype.notifyListeners = function() {
var this_ = this;
this.listeners.forEach(function(listener) {
listener(this_);
});
}
.
.
exports.TodoModel = TodoModel;
})(window);
.
.
window.addEventListener(’DOMContentLoaded’, function() {
var model = new TodoModel();
var newTodo = document.getElementById(’newTodo’);
var todoText = document.getElementById(’todoText’);
model.bindToView(todoText);
model.bindToInput(newTodo);
})
-----------------------------------------
参考になりそうなリンク
-----------------------------------------
http://d.hatena.ne.jp/graySpace/20110703/1309660990
http://hitsujiwool.tumblr.com/post/25562292144/module-patterns-of-javascript
http://lostlinksearch.net/blog/2012/10/javascript-%E3%81%AE%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%AE%E4%B8%AD%E3%81%AEthis%E3%81%AF%E4%BD%95%E3%82%92%E6%8C%87%E3%81%99%E3%81%8B/
http://qiita.com/takeharu/items/9935ce476a17d6258e27
-----------------------------------------
みんなの回答 22 件
中略
exports.TodoModel = TodoModel;
})(window);
即時関数というやつで、引数に渡したオブジェクトに
即時関数内で作成したオブジェクトを追加してあげる。
この場合はwindowオブジェクトのプロパティー(?)に
即時関数内のTodoModelを入れて上げている。
this.contents = ’’;
this.listeners = [];
}
TodoModelオブジェクトのインスタンスプロパティーとして
contentsとlistenersを作る。
この書き方はコンストラクタらしい。new TodoModel()みたいにしてインスタンス化する。
if (this.contents !== contents) {
this.contents = contents;
this.notifyListeners();
}
これは、TodoModel.setContents(contents);みたいに
メソッドを後で呼べるようになるのか??
そうだとしたら、インスタンス化されたTodoModelオブジェクトのcontentsプロパティーの値と、setContentsメソッドの引数に渡された値が違う場合のみ、if文内を実行する。インスタンスのcontensプロパティーに引数に渡された値を入れてあげて、その後にTodoModelオブジェクトのnotifyListeners()を実行する。どこでnotifyListeners()なんて作られていたっけ??
(4)
TodoModel.prototype.bindToInput = function(input) {
var _this = this;
var eventHandler = function(e) {
if (typeof(e.target.value) != ’undefined’) {
_this.setContents(e.target.value);
}
};
input.addEventListener(’keyup’, eventHandler);
input.addEventListener(’change’, eventHandler);
}
「var _this = this」ってのは何だろう。右側のthisは何を指しているのか?
_this.setContents()としているから、この時点でのthisはインスタンス自体を指しているっぽい。
下の2行でkeyupとchangeというイベントに上で定義したeventHandlerメソッドを紐づけている。
イベントが呼ばれると(e)のところにイベント関連の情報が自動で渡って、そこから取り出した値をsetContents()でインスタンスのcontentsプロパティーにセットしているっぽい。
(5)
TodoModel.prototype.addListener = function(listener) {
this.listeners.push(listener);
}
一つ上のブロックを飛ばして、さきにこっちにコメント付け。
インスタンス.addListener(listener)を呼ぶとインスタンスプロパティーのlisternesに引数に渡した値が追加されるっぽい。
(6)
TodoModel.prototype.bindToView = function(view) {
this.addListener(function(model) {
if (view.setValue) {
view.setValue(model.contents);
} else {
view.innerText=model.contents;
}
});
}
インスタンス.bindToView(view)を呼ぶと、インスタンスメソッドのインスタンス.addListenerを実行。
addLister()の引数が関数になっているのは何だろう。。。
しかも、その引数のなかの関数にも引数modelがあるけど、どこからこのmodelの引数は渡ってくるのか??
addLister()の引数内の関数では、bindToViewの引数に渡されたものにsetValueがあるかどうかをチェックして、ある場合はそのメソッドを引数model.contentsをわたして実行。
無い場合は、bindToViewの引数に渡したviewのinnerTextにmodel.contentsの内容をいれる。
this.contentsってのを最初の方で定義してたけど、それがmodel.contentsに呼応するかたちになるのか?
頑張ってください!応援しています。
(7)
TodoModel.prototype.notifyListeners = function() {
var this_ = this;
this.listeners.forEach(function(listener) {
listener(this_);
});
また、thisが出てきた。ちょっとちゃんと理解しないとまずいっぽい。
forEachっていうメソッドがたぶん、配列オブジェクトに備わっているっぽい。
forEachの引数にある関数がよくわからない。
さっきも引数に関数が入ってたけど、コールバックかなにかなのか。
引数のlistenerはどこから値が渡ってくるのか?
とりあえず、listenersに含まれるものをforEachして、listener(this_)って感じでループさせてるみたい。
インスタンス自体に引数に渡したlistenerっていうメソッドを読んであげてるらしい。
(8)
exports.TodoModel = TodoModel;
ここは単純に一番外にあるコンストラクタ関数の引数に渡したwindowオブジェクトのプロパティー(?)であるTodoModelに関数内で作ったTodoModelをいれてあげているだけ。
(9)
window.addEventListener(’DOMContentLoaded’, function() {
var model = new TodoModel();
var todoText = document.getElementById(’todoText’);
var newTodo = document.getElementById(’newTodo’);
model.bindToView(todoText);
model.bindToInput(newTodo);
})
DOMがロードされた時のイベント設定をしている。
さっき定義したTodoModelをインスタンス化して変数modelに入れてる。
HTMLドキュメントからIDがtodoTextってのとnewTodoってのを、それぞれ変数にいれてあげてる。
最後の2行がちょっと今までに出てきたやつが絡んで来るから、理解するのが大変。
ちょっと考える!
がんばれー!
Githubかなんかのコードレビューできるやつでやったらいいのに
優秀だなぁ。俺にはさっぱりだ。
がんばってください応援してます。
とりあえず、thisはあまり気にしなくてよいと思うよ。
そこからの理解だとかなり深くなるので。
閉じられたオブジェクトの中ではスコープが変わるので、thisの参照先も変わるくらいに思っていればいいんじゃないかな。そうなるとオブジェクトって何って話になるので更に深くなるがw
ありがとうございました!!
一先ず、このコードは理解出来ました!
コメントで励まし頂いた方、また、回答頂いた方ありがとうございました!!
もう少し、jsの基本的なところを2時間だけ時間を決めて集中してざっと把握して、そのあと、徹夜覚悟でjsコーディングの仕事開始します(汗)
すごいなー。
jsしばらく勉強してるのに、自分には分からない…
頭の出来の違いに凹んだ。
久しぶりに見た良いスレ。
夏休みは昨日までだぞ。
素朴な疑問。
jQueryじゃだめ?
トピ主は仕事でやってるのかな?
今日にはコーディング始めなきゃならないのに、基礎が分からない状態とか。無謀すぎるのではないか?何とか動くものが出来たとしても後のメンテナンスが大変そうだ。
仕事でやってるなら外注するのが最善だと思うんだが。
今さらだけどMVCやるならAngularとかBackbone使ったほうが楽だよ。
関連するトピックス