Top Banner
JavaScript Patterns 2011.01.16 @ sapporo.js @havanaclub_
41

JavaScript patterns

Jan 15, 2015

Download

Technology

 
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: JavaScript patterns

JavaScript Patterns2011.01.16 @ sapporo.js

@havanaclub_

Page 2: JavaScript patterns

自己紹介

•帯広から来ました

Page 3: JavaScript patterns

帯広

•超寒い

Page 4: JavaScript patterns

帯広

•ー17度

Page 5: JavaScript patterns

帯広

•雪:帰りがやばそう

Page 6: JavaScript patterns
Page 7: JavaScript patterns

•去年の9月くらい発売•例によってYohoo labs産(YSlowの作者Stoyan Stefanov)

• デザインパターン•コーディングパターン•アンチパターン•ライブラリ書きたい人向け

Page 8: JavaScript patterns

•良いところ:•ライブラリ実装者のノウハウこもりまくり

•悪いところ:•一見さんお断り• GoodPartsとか読みましょうって書いてある

Page 9: JavaScript patterns

基本部門

Page 10: JavaScript patterns

Global汚染の弊害

•よくわからんスクリプトが動的に読み込まれたときに動かんくなったりする

•広告JavaScript• ライブラリ相性•アクセス解析

Page 11: JavaScript patterns

ECMSScript 5strict mode

• var で確保された変数以外への代入はエラー(like Perl’s “use strict”)

functon some () {“use strict”;// do something...ubar = ‘dedededfe’ // error

}

Page 12: JavaScript patterns

ループとか

Page 13: JavaScript patterns

効率よくループ実行

Page 14: JavaScript patterns

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

for in と for の使い分け

Page 16: JavaScript patterns

for in loop

• array 以外の数え上げに利用すべき• arrayにも利用可能ではあるがプロパティがセットされてると誤爆する

•数え上げ順序が不定

Page 17: JavaScript patterns

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

比較演算子

Page 19: JavaScript patterns

暗黙の型キャストを避ける

•特に比較の場合。• type aware な === または !== を使用すべき

var zero = 0;if (zero === false) {

// good}

if (zero == false) {// anti pattern

}

Page 20: JavaScript patterns

数値データの解析

Page 21: JavaScript patterns

parseInt

• 数字が0ではじまっていると8進で解釈される

• parseIntと基数はセットで指定•Numberも使える

// anti patternparseInt(“012”) => 10

// good wayparseInt(“012”, 10) => 12Number(“012”) => 12

GoodPartsの後ろの方にも同記述

Page 22: JavaScript patterns

書き方系

•コーディング規約•命名規約•コメントの書き方• APIドキュメントの書き方• YUI doc(javadocみたいなの)• JSLint

Page 23: JavaScript patterns

オブジェクト関係

Page 24: JavaScript patterns

普通のコンストラクタ

•まあ普通

var Person function(name) {this.name = name;this.say = function(){ return “ test “ + this.name };

}

var person = new Person(“aaa”);

Page 25: JavaScript patterns

プロパティを変更させたくない(private

化)

Page 26: JavaScript patterns

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

オブジェクト関係

Page 28: JavaScript patterns

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

コンストラクタでthis 以外を返す

• that という名前にしておくと良い(命名規約的に)

• Singletonもこのパタンで

var Waffle = function() {var that = { msg : ‘yummy’ };return that;

}

var waffle = new Waffle(); // => {msg: ‘yummy’};

Page 30: JavaScript patterns

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

エラー関係

•実はnameとmessage属性が有るオブジェクトならなんでもthrowできる

try {throw {

name : “someError”,message : “error test”,test : function() { return name }

};} catch (e) {

console.log(e.test());}

Page 32: JavaScript patterns

エラー関係 (2)使い道

•エラーの付加情報とかを付けるのに便利

•でも普通にErrorサブクラス作った方が良い

try {throw {

name : “someError”,message : “error test”,errorStatus : 312

};} catch (e) {

return [message, e.errorStatus];}

Page 33: JavaScript patterns

ふつうの

•直接変更させたくない•入力値のバリデーション等

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

割と良く使うクロージャ利用:ロギング

•ロガーとクロージャの相性はかなり良い

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

部分適用版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

その他の内容

•関数•Curryingとかメモ化作成時分岐とか•オブジェクト生成•名前空間とか依存宣言とかModule• デザインパターンのJavaScript版• Deployment(圧縮等)

Page 37: JavaScript patterns

まとめ

•読むとjQueryとか作ってる人のきもちがわかるかも

Page 38: JavaScript patterns

宣伝•Hokkaido.pm #4 やります• 2/19 今回のゲスト:yusukebe さん•エロサイト管理者の憂鬱とか話してくれるらしいよ

• C++勉強会 2/26 • (東京のBoost勉強会のUSTみる予定)

Page 39: JavaScript patterns

補足:Curry化$(‘div1’).onclick = function () {

alert (‘aaa’);}$(‘div2’).onclick = function () {

alert (‘bbb’);}....

• onclickでそれぞれのdivに違うメッセージを出すパターン

•増えてくるとメンテナンスがめんどい

Page 40: JavaScript patterns

補足: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

補足: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 *)でオプションパラメータを登録できるようにするのが定石