Download - Clean Javascript
![Page 1: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/1.jpg)
Clean JavaScript
佐藤 竜之介(Ryunosuke SATO)Sapporo.js
SaCSS vol.29 - 2011.11.26
http://www.flickr.com/photos/hoshikowolrd/5151171470/
![Page 2: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/2.jpg)
提供
Sapporo.js
Community for people who like JavaScript.
![Page 4: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/4.jpg)
Sapporo.js
Now learning
![Page 5: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/5.jpg)
![Page 6: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/6.jpg)
I’m a programmer
![Page 7: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/7.jpg)
佐藤竜之介
@tricknotes
![Page 8: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/8.jpg)
よろしくお願いします
![Page 9: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/9.jpg)
Clean JavaScript
佐藤 竜之介(Ryunosuke SATO)Sapporo.js
SaCSS vol.29 - 2011.11.26
http://www.flickr.com/photos/hoshikowolrd/5151171470/
![Page 10: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/10.jpg)
今日のテーマ
![Page 11: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/11.jpg)
良いコード
![Page 12: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/12.jpg)
とは?
![Page 13: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/13.jpg)
コードだけが良いのではなく、良い振る舞いを行えるのが良いコードである
![Page 14: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/14.jpg)
よく出てくる問題に対応するための法則性
良い習慣
![Page 15: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/15.jpg)
どういうときにどうするのが良いコードにつながっていくか
![Page 16: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/16.jpg)
対象者
![Page 17: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/17.jpg)
普段 JavaScript を書いているひと良いコードを書きたいと思っているひと良いコードに興味があるひと
![Page 18: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/18.jpg)
普段 JavaScript を書いているひと良いコードを書きたいと思っているひと良いコードに興味があるひと
![Page 19: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/19.jpg)
about JavaScript
![Page 20: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/20.jpg)
Works in everywhere!
![Page 21: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/21.jpg)
interesting!
http://www.flickr.com/photos/peco-sunnyday/2752403413/
![Page 22: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/22.jpg)
I like
![Page 23: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/23.jpg)
JavaScript is most popular!
https://github.com/languages
![Page 24: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/24.jpg)
but...
![Page 25: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/25.jpg)
difficult
http://www.flickr.com/photos/maynard/6105929170/
![Page 26: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/26.jpg)
Now training...
![Page 27: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/27.jpg)
??How to face the difficulty
![Page 28: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/28.jpg)
良い習慣
![Page 29: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/29.jpg)
装備を整えて、挑む準備が必要
![Page 30: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/30.jpg)
Oops... :(
http://www.flickr.com/photos/cholovak/4500742434/
![Page 31: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/31.jpg)
some ideas
![Page 32: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/32.jpg)
DOMwith
![Page 33: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/33.jpg)
point
![Page 34: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/34.jpg)
HTML と JavaScript をいかに分けるか
![Page 35: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/35.jpg)
画面 ロジック
HTML JavaScript
![Page 36: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/36.jpg)
画面 ロジック
HTML JavaScript
here!
![Page 37: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/37.jpg)
practice
![Page 38: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/38.jpg)
problem
どこで JavaScript のイベントが設定されているのかわかりづらい
イベントは外側から - Attach events from outer -
![Page 39: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/39.jpg)
solution
HTML の 属性として設定するのをやめてJavaScript からのみイベントを設定する
イベントは外側から - Attach events from outer -
![Page 40: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/40.jpg)
<a onclick=”showMessage()”>Click me</a>
code smell
イベントは外側から - Attach events from outer -
![Page 41: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/41.jpg)
<a id=”showMessage”>Click me</a>
var a = document.getElementById(‘showMessage’);a.addEventListener(‘click’, showMessage);
イベントは外側から - Attach events from outer -
improvement
![Page 42: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/42.jpg)
HTML の idやclassに依存したコードになっていて、画面を修正するたびに動かなくなる部分がある
セレクタからの分離 - Separate from Selector -
problem
![Page 43: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/43.jpg)
HTML の id や class に極力依存しない設計にする
セレクタからの分離 - Separate from Selector -
solution
![Page 44: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/44.jpg)
function showPhoto(photoId) { var photo = document.getElementById(‘photo-’ + photoId); // do ...}
セレクタからの分離 - Separate from Selector -
![Page 45: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/45.jpg)
function showPhoto(photoId) { var photo = document.getElementById(‘photo-’ + photoId); // do ...}
セレクタからの分離 - Separate from Selector -
code smell
![Page 46: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/46.jpg)
var showPhoto = function(element) { // do ...}
var photo = document.getElementById(‘photo-12’);showPhoto(photo);
セレクタからの分離 - Separate from Selector -
improvement
![Page 47: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/47.jpg)
モジュール化 - modulized functions -
ファイルの数が多く、探したい関数がなかなか見つけられない
problem
![Page 48: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/48.jpg)
ファイル名を表すモジュールにまとめる
モジュール化 - modulized functions -
solution
![Page 49: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/49.jpg)
// users.jsvar showUserName = function() { // do somethig}
var showUserAge = function(){ // do somethig}
var validateUserForm = function() { // do somethig}
モジュール化 - modulized functions -
code smell
![Page 50: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/50.jpg)
// users.jsvar showUserName = function() { // do somethig}
var showUserAge = function(){ // do somethig}
var validateUserForm = function() { // do somethig}
global
モジュール化 - modulized functions -
![Page 51: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/51.jpg)
// users.jsvar users = {};
users.showName = function () { // do somethig}
users.showAge = function (){ // do somethig}
users.validateForm = function () { // do somethig}
global
モジュール化 - modulized functions -
![Page 52: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/52.jpg)
// users.js(function(global) { global.users = {};
users.showName = function () { // do somethig }
// ...)(this);
global
モジュール化 - modulized functions -
improvement
![Page 53: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/53.jpg)
JavaScript のイベントで、DOM の元々の動作を上書きしたい
振る舞いの上書き - overwrite behavior -
problem
![Page 54: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/54.jpg)
DOM が元々持っている属性を利用する足りなければ、DOM に属性を追加する
振る舞いの上書き - overwrite behavior -
solution
![Page 55: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/55.jpg)
振る舞いの上書き - overwrite behavior -
// using jQuery
$(‘a#showDialog’).click(function() { $.ajax(‘/about’, { success: function(html) { // do something... } });});
code smell
![Page 56: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/56.jpg)
// using jQuery
$(‘a#showDialog’).click(function() { $.ajax($(this).attr(‘href’), { success: function(html) { // do something... } });});
振る舞いの上書き - overwrite behavior -
improvement
![Page 57: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/57.jpg)
コールバック関数を深く設定してしまっていて、一つの処理が大きくなってしまっている。同じ変数があちこちにちらばっていて、
処理をわけるのが困難である
浅いスコープ - shallow scope -
problem
![Page 58: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/58.jpg)
変数が、2段以上の function のスコープをまたがないようにする
→引数や、 this で渡すようにする
浅いスコープ - shallow scope -
solution
![Page 59: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/59.jpg)
// using jQuery
var $elements = $(‘a#remote’);$elements.click(function() { var url = $(this).attr(‘href’); $.ajax(url, { success: function(html) { var text = $(html).text(); $element.text(text); } }); return false;});
浅いスコープ - shallow scope -
![Page 60: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/60.jpg)
// using jQuery
var $elements = $(‘a#remote’);$elements.click(function() { var url = $(this).attr(‘href’); $.ajax(url, { success: function(html) { var text = $(html).text(); $element.text(text); } }); return false;});
deep
浅いスコープ - shallow scope -
code smell
![Page 61: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/61.jpg)
// using jQuery
var $elements = $(‘a#remote’);$elements.click(function() { var url = $(this).attr(‘href’); $.ajax(url, { success: function(html) { var text = $(html).text(); $(this).text(text); }, context: this }); return false;});
浅いスコープ - shallow scope -
improvement
![Page 62: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/62.jpg)
DOMをモデルオブジェクトへ - DOM to model -
DOM にいくつかのフラグを設定したり、まとめて操作を行いたい部分がある
problem
![Page 63: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/63.jpg)
DOM をラップするオブジェクトを作成し、一連の処理をメソッドにする
DOMをモデルオブジェクトへ - DOM to model -
solution
![Page 64: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/64.jpg)
var element = document.getElementById(‘message’);element.addEventListener(‘click’, function() { // this == element if (this.getAttribute(‘data-is-checked’)) { this.setAttribute(‘data-is-checked’, true); this.innerText = ‘clicked!’; }});
DOMをモデルオブジェクトへ - DOM to model -
code smell
![Page 65: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/65.jpg)
var domToModel = function(element, Model) { var method, name, object, parent, proto; model = Object.create(element); proto = Model.prototype; for (name in proto) { method = proto[name]; model[name] = method; } Model.apply(model); return model;};
var CustomElement = function() {};CustomElement.prototype.showText = function() { if (!this.getAttribute(‘data-is-checked’)) { this.setAttribute(‘data-is-checked’, true); this.innerText = ‘clicked!’; }};
var element = document.getElementById(‘message’);var model = domToModel(element, CustomElement);model.addEventListener(‘click’, function() { model.showText();});
DOMをモデルオブジェクトへ - DOM to model -
![Page 66: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/66.jpg)
var element = document.getElementById(‘message’);var model = domToModel(element, CustomElement);model.addEventListener(‘click’, function() { model.showText();});
DOMをモデルオブジェクトへ - DOM to model -
var domToModel = function(element, Model) { var method, name, object, parent, proto; model = Object.create(element); proto = Model.prototype; for (name in proto) { method = proto[name]; model[name] = method; } Model.apply(model); return model;};
var CustomElement = function() {};CustomElement.prototype.showText = function() { if (!this.getAttribute(‘data-is-checked’)) { this.setAttribute(‘data-is-checked’, true); this.innerText = ‘clicked!’; }};
![Page 67: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/67.jpg)
var element = document.getElementById(‘message’);var model = domToModel(element, CustomElement);model.addEventListener(‘click’, function() { model.showText();});
DOMをモデルオブジェクトへ - DOM to model -
improvement
var domToModel = function(element, Model) { var method, name, object, parent, proto; model = Object.create(element); proto = Model.prototype; for (name in proto) { method = proto[name]; model[name] = method; } Model.apply(model); return model;};
var CustomElement = function() {};CustomElement.prototype.showText = function() { if (!this.getAttribute(‘data-is-checked’)) { this.setAttribute(‘data-is-checked’, true); this.innerText = ‘clicked!’; }};
![Page 68: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/68.jpg)
画面とロジックの分離 - separate logic with view -
ロジックと画面への情報更新が強く結びついていて、どちらか片方だけの変更が困難である
problem
![Page 69: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/69.jpg)
ロジックと画面への情報更新を分割し、イベントを通じて変更を通知する
solution画面とロジックの分離 - separate logic with view -
![Page 70: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/70.jpg)
function createTimer() { var timerId; var startTimer = function(millisec) { timerId = setTimeout(function() { $(‘.timeout’).text(‘finished’); }, millisec); } var stopTimer = function() { clearTimeout(timerId); } return { startTimer: startTimer, stopTimer: stopTimer }}
画面とロジックの分離 - separate logic with view -
![Page 71: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/71.jpg)
function createTimer() { var timerId; var startTimer = function(millisec) { timerId = setTimeout(function() { $(‘.timeout’).text(‘finished’); }, millisec); } var stopTimer = function() { clearTimeout(timerId); } return { startTimer: startTimer, stopTimer: stopTimer }}
画面とロジックの分離 - separate logic with view -
view
code smell
![Page 72: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/72.jpg)
function Timer(millisec) { this. millisec = millisec; this.callbacks = []; this.timerId = null;}
Timer.prototype.afterFinish = function(callback) { return this.callbacks.push(callback);};
Timer.prototype.start = function() { var callbacks = this.callbacks; this.timerId = setTimeout(function() { var callback, i, length; for (i = 0, length = callbacks.length; i < length; i++) { callback = callbacks[i]; callback(); } }, this. millisec);};
Timer.prototype.stop = function() { clearTimeout(this.timerId);}
var timer = new Timer(1000);timer.afterFinish(function() { $('.timer .message').text('Finished!!');});timer.start();
画面とロジックの分離 - separate logic with view -
![Page 73: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/73.jpg)
var timer = new Timer(1000);timer.afterFinish(function() { $('.timer .message').text('Finished!!');});timer.start();
model
view
function Timer(millisec) { this. millisec = millisec; this.callbacks = []; this.timerId = null;}
Timer.prototype.afterFinish = function(callback) { return this.callbacks.push(callback);};
Timer.prototype.start = function() { var callbacks = this.callbacks; this.timerId = setTimeout(function() { var callback, i, length; for (i = 0, length = callbacks.length; i < length; i++) { callback = callbacks[i]; callback(); } }, this. millisec);};
Timer.prototype.stop = function() { clearTimeout(this.timerId);}
画面とロジックの分離 - separate logic with view -
improvement
![Page 74: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/74.jpg)
A tiny fraction
![Page 75: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/75.jpg)
独立しているわけではない相互に関連している
![Page 76: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/76.jpg)
others...
![Page 77: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/77.jpg)
Pure JavaScript
![Page 78: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/78.jpg)
![Page 79: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/79.jpg)
Application
![Page 80: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/80.jpg)
https://gist.github.com/1362110元記事: http://blog.nodejitsu.com/scaling-isomorphic-javascript-code
![Page 81: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/81.jpg)
http://documentcloud.github.com/backbone/
![Page 83: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/83.jpg)
良いコードを書くためには
![Page 84: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/84.jpg)
http://www.flickr.com/photos/bonguri/4610536789/
interest
![Page 85: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/85.jpg)
reading
![Page 86: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/86.jpg)
Good text
![Page 87: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/87.jpg)
writing
![Page 88: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/88.jpg)
![Page 89: Clean Javascript](https://reader037.vdocuments.us/reader037/viewer/2022102415/5558bd13d8b42a7e298b5152/html5/thumbnails/89.jpg)
http://www.flickr.com/photos/tsukacyi/4848685561/
Shall we learn about
Clean JavaScript?