Successfully reported this slideshow.

More Related Content

More from Osamu Monoe

Related Audiobooks

Free with a 14 day trial from Scribd

See all

モテる JavaScript

  1. 1. モテる JavaScript 日本マイクロソフト株式会社 デベロッパー& プ ラットフォーム統括本部 物江修 Twitter : osamum_MS Blog : http://blogs.msdn.com/b/osamum/
  2. 2. 目的 • 他人に見られて恥ずかしくない コードを書く • 格好良い JavaScript コードを 書いてモテる
  3. 3. アジェンダ •知っておきたい JavaScript の 慣例的な記述方法とマナー •使われているとなんかカッコ良い JavaScript の機能 •最近、こんなふうに書いてます。
  4. 4. 知っておきたい JavaScript の 慣例的な記述方法とマナー
  5. 5. 変数/関数の命名規則 • 基本 var fistName; (キャメルケース) • コンストラクタ var calendar = new CalenderCtrl(); (先頭が大文字) • this (現在の名前空間) var that = this; • 定数 var GENERAL_API_KEY = "4fh5cv$sp"; • プライベート var _userName = "user01";
  6. 6. 変数/関数を判別する工夫 •関数 : 動詞を先頭 ex) setHandler, getInfo, loadContent •変数 : 単語間を _ (アンダースコア) で ex) var first_name = "";
  7. 7. 変数を宣言する場所 •関数の先頭 •すべての変数 function myFunc(){ var shopName; var address; var phone; var catchCopy; ・ ・ function myFunc(){ var shopName, address, phone, catchCopy; ・ ・
  8. 8. スコープ (1/2) • JavaScript の変数スコープは関数単位 //変数 i と fullName のスコープは for 文内に閉じていな い for (var i = 0; i < length; i++) { var fullName = items[i].firstName + " " items[i].lastName; : //以下は期待どおりの動作とならない for (var i=0; i<5; i++) { console.log("Outer loop " + i); for (var i=0; i<10; i++) { console.log("Inner loop " + i); } }
  9. 9. • 宣言されていない変数は巻き上げられる • 複数回宣言可能 (上書きれる) スコープ (2/2) function myFunc(){ $ = "Hello"; //jQuery を使用していた場合、正常に動作しなく なる 意図しない名前空間の変数書き換え ⇒ 名前空間の汚染
  10. 10. 名前空間を汚染しないための工夫 • “use strict” の使用 • 即時実行関数に閉じる <script> (function(){ "use strict"; onload = function(){ var variable1, variable2, variable3; //ページ読み込み時の処理 }; function otherFunction(){ //関数の処理 }; })(); </script>
  11. 11. オブジェクトを利用した書き方(1) var myUtil = { methodA : function () { //method A の処理 return resultValue; }, methodB : function(arg){ //method B の処 理 return resultValue; } }; //呼び出し方 var variable = myUtil.methodA();
  12. 12. オブジェクトを利用した書き方(2) var myUtil = {}; myUtil.methodA = function () { //method A の処理 return resultValue; }; myUtil.methodB = function (arg) { //method B の処理 return resultValue; }; //呼び出し方は同じ var variable = myUtil.methodA();
  13. 13. 中括弧({})の書き方 (1/2) • 中括弧の開始タグの前で改行しない • 暗黙的 ; (セミコロン) の挿入による意図 しない動作となる場合がある function userInfo(){ return { firstName : "ひろし", lastName : "山田", age : 23}; } ×〇 function userInfo() { return { firstName : "ひろし", lastName : "山田", age : 23}; } エラーが発生
  14. 14. 中括弧({})の書き方 (2/2) • if 文は {} を省略せずに書く if( itemslength == MAX_LENGTH) countLabel.innerText = "Full"; else countLabel.innerText = itemslength; if( itemslength == MAX_LENGTH) { countLabel.innerText = "Full"; }else{ countLabel.innerText = itemslength; } △ 〇
  15. 15. DOM アクセスについて • DOM ツリーを探すのでアクセスにはコストがかかる • 2 回以上アクセスする際はインスタンスを変数に //一般的に使用される DOM エレメントのインスタンスの取得法 var element = document.getElementById("エレメントの ID"); .getElementByName("エレメントの名前"); .querySelector("CSS セレクタ"); .activeElement(); .all();
  16. 16. DOM アクセスの例 //非常に効率が悪い例 for(var i=0; i < document.getElementById(“itemList”).childNodes.length; i++){ document.getElementById("itemList").childNodes[i].innerText = "アイテム" + i; } //ロスを減らした例 var nodes = document.getElementById("itemList").childNodes; var length = nodes.length; for(var i=0; i< length; i++){ nodes[i].innerText = "アイテム" + i; }
  17. 17. ここまでのまとめ •慣例的な記述方法 • 可読性を高めるため • メンテナンス性を高めるため • 意図しない動作を避けるため • 他者に迷惑をかけないためのマナー
  18. 18. 使われていると なんかカッコ良い JavaScript の機能
  19. 19. あいまいな評価の利用 (1/3) • JavaScript の 5 つの false 以下はいずれも false と判断される false null undefined "" (空文字) 0 NaN (not a number)
  20. 20. if(stringData!="") ⇒ if(stringData) あいまいな評価の利用 (2/3) いろいろな使いみち if(myObject) //オブジェクトのインスタンスの有 無 if(document.addEventListener) //メソッドの有無 if(items.length) //要素の有無 (数)
  21. 21. 定義済み判定のさらに短い書式 //変数の初期値設定 function(stringArg){ stringArg = stringArg || "defaultValue"; //安全な名前空間の登録 var myApp = myApp||{};
  22. 22. •注意が必要な場合も あいまいな評価 (3/3) 以下の式は正しく評価されない console.log(0 == ''); //true console.log(0 == '0'); //true console.log(false == '0'); //true console.log(null == undefined); //true console.log(0 == 'trn'); //true
  23. 23. あいまいな評価を避けるには === !== •厳密な評価が可能 イコール Not イコール console.log(null === undefined); //false
  24. 24. 即時実行関数 • (function(){//処理})(); • 一か所からのみ呼び出される • 名前空間を使用しない var shopName = item.shopName; var avgFare = item.avgFare; var creditCard = (function(sepChar){ var dotList = "", cardList = item.creditCardList, length = cardList.length; for(var i=0; i<= length; i++){ dotList += cardList[i].name + sepChar; } return dotList; })(",");
  25. 25. クロージャー(1/3) • 渡された引数の値を保持する function makeAdder(x){ return function(y){ return x + y; } } var add5 = makeAdder(5); var add10 = makeAdder(10); console.log(add5(2)); //7 console.log(add10(2)); //12
  26. 26. クロージャー(2/3) [[scoope]] makeAddr add5 add10 function(y) {return x + y} [[scoope]] function(y) {return x + y} [[scoope]] [[scoope]] x : 10 [[scoope]] x : 5 function (x) { return function( y ) { } }
  27. 27. クロージャー(2/3) var ctrl_listView = document.getElementById("itemList"), ctrl_item = null; for(var i=0; i <=5; i++){ crtl_item = document.createElement("li"); crtl_item.innerText = "リンク" + i; crtl_item.addEventListener("click", function (index) { return function(){ console.log(index + "番目がクリックされました。"); } }(i) , false); ctrl_listView.appendChild(crtl_item); } • ex) リストに生成時のインデックスを保持
  28. 28. メソッドチェーン (1/2) • ワンライナー(一行)で複数メソッドの呼び出し • オブジェクトツリーの検索処理の軽減 01| myPage.setCtrl(); 02| myPage.setHendler(); 03| myPage.loadData(); 01| myPage.setCtrl().setHendler().loadData();
  29. 29. メソッドチェーン (2/2) var myPage = { methodOne : function(){ console.log("ONE"); return this; }, methodTwo : function(){ console.log("TWO"); return this; }, methodThree : function(){ console.log("THREE"); return this; } } //呼び出し myPage.methodOne().methodTwo().methodThree();
  30. 30. ここまでのまとめ • JavaScript の良い意味での「曖昧さ」 を理解してうまく使うことでコンパクト で効率の良いコードが書ける • 関数の実行タイミング、メモリの使われ 方をすることで頓智の効いたコードが書 ける
  31. 31. 最近、こんなふうに 書いてます。
  32. 32. 完結したページ/コントロールを 1 対 1 のオブジェクトで管理 var thisPage ={ ctrls:{ //コントロールの //インスタンスを保持 }, init:{ //ページの初期化関数群 }, handlers:{ //イベントハンドラ群 }, util:{ //一般関数群 } }
  33. 33. 初期化オブジェクトの中身 var thisPage ={ ctrls:{ listBox:null }, init:{ setCtrls:function(){ this.ctrl.listBox = id$("listBox"); return this; }, setHandlers:function(){ this.ctrl.listBox.addEventListener("change", this.hendlers.changeItem,false); return this; }, lenderPage:function(){ //listBox へのデータロード処理等 return this; } }
  34. 34. 初期化メソッドの呼び方 onload = function(){ thisPage.init.setCtrls() .setHandlers() .lenderPage(); } //正常時、エラー時に実行する関数を引数に .lenderPage(success,error);
  35. 35. Web ページの場合の応用 ・ブラウザ間のイベント設定の記述の違いを吸収する var util ={ addEvent:null, init: function () { if(document.addEventListener) { this.addEvent = function(element, type, handler){ element.addEventListener(type, handler, false); } }else if(document.attachEvent) { this.addEvent = function(element, type, handler){ element.attachEvent('on' + type, handler); }}}} //初期化 util.init(); //イベントハンドラの設定 util.addEvent(document.getElementById("button"));
  36. 36. ここまでのまとめ • インタラクティブに動作する Web アプ リケーションは、ページをオブジェクト を介して抽象化すると扱いやすい
  37. 37. まとめ •日々是学び •「オトコならシャツ一枚にもこ だわれ」⇒「技術者ならコード 一行にこだわれ」 enjoy!
  38. 38. 参考 O’RELLY Japan JavaScript http://www.oreilly.co.jp/books/9784873113296/
  39. 39. 参考 O’RELLY Japan JavaScript: The Good Parts――「良いパーツ」による ベストプラクティス http://www.oreilly.co.jp/books/9784873113913/
  40. 40. 参考 O’RELLY Japan JavaScriptパターン ――優れたアプリケーションの ための作法 http://www.oreilly.co.jp/books/9784873114880/

×