JavaScript patterns
-
Upload
norihito-yamakawa -
Category
Technology
-
view
1.787 -
download
2
description
Transcript of JavaScript patterns
![Page 1: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/1.jpg)
JavaScript Patterns2011.01.16 @ sapporo.js
@havanaclub_
![Page 2: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/2.jpg)
自己紹介
•帯広から来ました
![Page 3: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/3.jpg)
帯広
•超寒い
![Page 4: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/4.jpg)
帯広
•ー17度
![Page 5: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/5.jpg)
帯広
•雪:帰りがやばそう
![Page 6: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/6.jpg)
![Page 7: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/7.jpg)
•去年の9月くらい発売•例によってYohoo labs産(YSlowの作者Stoyan Stefanov)
• デザインパターン•コーディングパターン•アンチパターン•ライブラリ書きたい人向け
![Page 8: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/8.jpg)
•良いところ:•ライブラリ実装者のノウハウこもりまくり
•悪いところ:•一見さんお断り• GoodPartsとか読みましょうって書いてある
![Page 9: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/9.jpg)
基本部門
![Page 10: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/10.jpg)
Global汚染の弊害
•よくわからんスクリプトが動的に読み込まれたときに動かんくなったりする
•広告JavaScript• ライブラリ相性•アクセス解析
![Page 11: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/11.jpg)
ECMSScript 5strict mode
• var で確保された変数以外への代入はエラー(like Perl’s “use strict”)
functon some () {“use strict”;// do something...ubar = ‘dedededfe’ // error
}
![Page 12: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/12.jpg)
ループとか
![Page 13: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/13.jpg)
効率よくループ実行
![Page 14: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/14.jpg)
for (var i = 0; i < myarray.length; i++ ) {// = some
}
for (var i = 0, max = myarray.length; i < max ;i++ ) {// = some
}
for loopCashing collection length
190 times faster(IE7)
毎回DOM問い合わせが入るのでキャッシュ
![Page 15: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/15.jpg)
for in と for の使い分け
![Page 16: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/16.jpg)
for in loop
• array 以外の数え上げに利用すべき• arrayにも利用可能ではあるがプロパティがセットされてると誤爆する
•数え上げ順序が不定
![Page 17: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/17.jpg)
for in loop : 2
• prototype chainで継承してきた値のフィルタにはobj.hasOwnProperty()を使う
var man = { heads : 2, legs : 2 };Object.prototype.clne = function() {};
for (var i in man) {if (man.hasOwnProperty(i)) {
console.log(i, ‘:’, man[i]);} # => heads:2
} # legs:2
GoodPartsにも同記述
![Page 18: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/18.jpg)
比較演算子
![Page 19: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/19.jpg)
暗黙の型キャストを避ける
•特に比較の場合。• type aware な === または !== を使用すべき
var zero = 0;if (zero === false) {
// good}
if (zero == false) {// anti pattern
}
![Page 20: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/20.jpg)
数値データの解析
![Page 21: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/21.jpg)
parseInt
• 数字が0ではじまっていると8進で解釈される
• parseIntと基数はセットで指定•Numberも使える
// anti patternparseInt(“012”) => 10
// good wayparseInt(“012”, 10) => 12Number(“012”) => 12
GoodPartsの後ろの方にも同記述
![Page 22: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/22.jpg)
書き方系
•コーディング規約•命名規約•コメントの書き方• APIドキュメントの書き方• YUI doc(javadocみたいなの)• JSLint
![Page 23: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/23.jpg)
オブジェクト関係
![Page 24: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/24.jpg)
普通のコンストラクタ
•まあ普通
var Person function(name) {this.name = name;this.say = function(){ return “ test “ + this.name };
}
var person = new Person(“aaa”);
![Page 25: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/25.jpg)
プロパティを変更させたくない(private
化)
![Page 26: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/26.jpg)
private
•クロージャとの組み合わせでまあ可能
function Gadget () { var name = “aaaa”;
this.getName = function () { return name};this.setName = function (n) { name = n };
}
var g = new Gadget(); g.getName(); g.setName(‘test’);g.name = “change”;
![Page 27: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/27.jpg)
オブジェクト関係
![Page 28: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/28.jpg)
new を忘れると
• thisがグローバルオブジェクトを指す• ECMAScript 5 strict modeだとグローバルオブジェクトを指さなく出来る
var Person = function(name) {this.name = name;this.say = function(){ return “ test “ + this.name };
}
var person = Person(“aaa”);person.name // => this will reference window.name or global symbol ‘name’
![Page 29: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/29.jpg)
コンストラクタでthis 以外を返す
• that という名前にしておくと良い(命名規約的に)
• Singletonもこのパタンで
var Waffle = function() {var that = { msg : ‘yummy’ };return that;
}
var waffle = new Waffle(); // => {msg: ‘yummy’};
![Page 30: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/30.jpg)
newが無くてもオブジェクトnew
• newの自己呼び出しテクニック• thisが関数ローカルスコープでなさそうだったらあらためてnew
function Waffle() {if(!(this instanceof Waffle)) {
return new Waffle();}
this.tastes = ‘yummy’ ;}var waffle = Waffle(); // is instance of Waffle
![Page 31: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/31.jpg)
エラー関係
•実はnameとmessage属性が有るオブジェクトならなんでもthrowできる
•
try {throw {
name : “someError”,message : “error test”,test : function() { return name }
};} catch (e) {
console.log(e.test());}
![Page 32: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/32.jpg)
エラー関係 (2)使い道
•エラーの付加情報とかを付けるのに便利
•でも普通にErrorサブクラス作った方が良い
try {throw {
name : “someError”,message : “error test”,errorStatus : 312
};} catch (e) {
return [message, e.errorStatus];}
![Page 33: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/33.jpg)
ふつうの
•直接変更させたくない•入力値のバリデーション等
function Gadget () { this.name = “aaaa”;
this.getName = function () { return name};this.setName = function (n) { name = n };
}
var g = new Gadget();g.name = “changed”;
![Page 34: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/34.jpg)
割と良く使うクロージャ利用:ロギング
•ロガーとクロージャの相性はかなり良い
var blog = Blog.load( {blog_id: 2} );var entry = blog.entries().first();
var logger = function(msg) { console.log(“Blog : “ + blog.id + “ Entry : “ + entry.id + msg)};
logger(“see this”) / /=> “Blog id : 2 Entry id : 3 see this”
![Page 35: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/35.jpg)
部分適用版var blog = Blog.load( {blog_id: 2} );var entry = blog.entry();
function cusutom_logger(blog_id, entry_id) {return function(msg) {
console.log(“Blog : “ + blog_id + “ Entry : “ + entry_id + msg)};}
var logger = cusutom_logger(blog.id, entry.id);logger(“see this”) / /=> “Blog id : 2 Entry id : 3 see this”
![Page 36: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/36.jpg)
その他の内容
•関数•Curryingとかメモ化作成時分岐とか•オブジェクト生成•名前空間とか依存宣言とかModule• デザインパターンのJavaScript版• Deployment(圧縮等)
![Page 37: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/37.jpg)
まとめ
•読むとjQueryとか作ってる人のきもちがわかるかも
![Page 38: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/38.jpg)
宣伝•Hokkaido.pm #4 やります• 2/19 今回のゲスト:yusukebe さん•エロサイト管理者の憂鬱とか話してくれるらしいよ
• C++勉強会 2/26 • (東京のBoost勉強会のUSTみる予定)
![Page 39: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/39.jpg)
補足:Curry化$(‘div1’).onclick = function () {
alert (‘aaa’);}$(‘div2’).onclick = function () {
alert (‘bbb’);}....
• onclickでそれぞれのdivに違うメッセージを出すパターン
•増えてくるとメンテナンスがめんどい
![Page 40: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/40.jpg)
補足:Curry化(2)$(‘div1’).onclick = gen_alert(‘aaa’);$(‘div2’).onclick = gen_alert(‘bbb’);function gen_alert(msg) {
return function { alert(msg) };}
•関数のカスタマイズ=引数の消去•「指定したメッセージをalertで表示する引数なしの関数」をつくる関数をつくり、それの返値をコールバック登録
![Page 41: JavaScript patterns](https://reader035.fdocuments.in/reader035/viewer/2022070303/54b78d694a7959db528b4979/html5/thumbnails/41.jpg)
補足:Cコールバックtypedef int (*CALLBACK)(* void); // pointer type for int func(void *)typedef struct {
CALLBACK handler;void * option;
} callback_data;
callback_data callback;void register_callback (CALLBACK f, void* opt) {
callback.handler = f; callback.option = opt;}void invoke_callback() {
CALLBACK f = callback.handler;f(callback.option);
}
char * msg = “message”;int speak() { printf (“%s”, (char *)void) };main () {
register_callback((CALLBACK)speak, (void *)msg);invoke_callback();
}
• (void *)でオプションパラメータを登録できるようにするのが定石