Advertisement

覚醒!JavaScript

フロントエンドエンジニア at gumi Inc
Aug. 6, 2014
Advertisement

More Related Content

Slideshows for you(20)

Advertisement

覚醒!JavaScript

  1. 覚醒!JavaScript 株式会社 gumi 原口
  2. 自己紹介 • 原口 剛 (はらぐち ごう) • フロントエンドエンジニア • 2012年 gumi入社 • スマホWebゲーム
  3. 黒歴史 •28歳でJavaでHelloWorld!を書く •受託システム開発
 Java+ActionScript3 •ソシャゲ開発
 ケータイFlash制作 •スマホ対応で初めてHTML+CSSを書く
 JavaScriptほとんど書いてない •某価格比較サイトのコーダー業務
 スマホ版のカルーセルUI実装で初めて 本格的にJavaScriptにちゃんと触れる
  4. が、しかし!!
  5. それは、”jQueryJavaScript”だった・・・ $('.carousel-prev').click(function () { $('.carousel').carousel('scroll', '-=1'); }); $('.carousel-next').click(function () { $('.carousel').carousel('scroll', '+=1'); }); (勝手に命名)
  6. jQueryじゃダメなの!? 小規模ならいいかもね 中・大規模だと破綻するかもね
  7. なんでjQueryじゃダメなの!? ネームスペースの問題・ハンドラ関数の爆発的増加・ コード再利用のやりづらさetc と、その話はおいといて・・・
  8. 模範的なJavaScriptプロジェクト プログラミング上達のコツは? 教わるよりも学びましょう! 守・破・離
  9. 模範的なJavaScriptプロジェクト jQuery, Underscore.js, Knockout.js等々 著名なライブラリやフレームワークの中身を 理解可能なレベルになっておきたい! そこから学べる要素が必ずあるはずです!
  10. 理解できるレベルとは? • なんとなくではなく、明確に理解している • ブラックボックス症候群にはご注意を!
  11. アジェンダ •JavaScriptオブジェクト •関数(Function()) •グローバルオブジェクト •this •スコープとクロージャ
  12. JavaScriptオブジェクト
  13. JavaScriptオブジェクト JavaScriptの世界では、
 ほぼすべてがオブジェクトそのものか、
 もしくはオブジェクトのようにふるまう
  14. オブジェクト 『名前』と『値』を持つプロパティを
 格納するコンテナ var man = new Object(); man.living = true; man.age = 35; man.gender = 'male'; 値 名前
  15. メソッド 単なるデータのみだと、オブジェクトはJSONのよ うなデータベースすぎないが、オブジェクトには ふるまいを付与できる
  16. メソッド var man = new Object(); man.living = true; man.age = 35; man.gender = ‘male'; man.getGender = function(){ return man.gender; } ふるまい
  17. コンストラクタ関数 一見、普通の関数 一般的に関数名の先頭文字を大文字にしている new演算子を伴って呼び出された場合、コンスト ラクタ関数は特別な役割をする
  18. 特別な役割? 本来return文を宣言しない場合にはfalse相当の値を 返すところ、コンストラクタ関数は代わりに新た に生成されるオブジェクトを返す コンストラクタ関数中のthisは、戻り値であるオブ ジェクトを示す予約語
  19. var Person = function (living, age, gender) { this.living = living; this.age = age; this.gender = gender; this.getGender = function () { return this.gender; }; }; var haraguchi_10 = new Person(true, 10, ‘male’); var haraguchi_20 = new Person(true, 20, ‘male’); var haraguchi_30 = new Person(true, 30, ‘male'); コンストラクタ関数
  20. ネイティブコンストラクタ JavaScriptには、9つのネイティブオブジェクトコン ストラクタが存在する JavaScriptのさまざまな機能を整えるためにも使用さ れる 関数は、Function()コンストラクタから生成されるオ ブジェクトで、new演算子とともに使用することで、 コンストラクタとして他のオブジェクトを生成する
  21. 9つのオブジェクト Number() 、String()、 Boolean()、 Object()、 Array() Function()、 Date()、 RegExp()、 Error() 言語の深層部を理解するには、以上のネイティブ オブジェクトコンストラクタ関数を知っておくこ とが になる
  22. リテラル オブジェクト生成のショートカット リテラルはnew演算子が行うことを隠 しているにすぎない オブジェクトの生成はリテラルの方がお手軽だし便利 var myNumber = new Number(10000); var myNumberLiteral = 10000; console.log(myNumber.constructor, myNumberLiteral.constructor); Number() Number() newする リテラル
  23. プリミティブ値 null, undefiend, ’string’, 10, true, falseなどは
 オブジェクトではなくプリミティブ型 一部のプリミティブ型はオブジェクトのように扱 うとオブジェクトのようにふるまう var name= “Haraguchi”; console.log(name.toString()); オブジェクト型化
  24. オブジェクトの保持 • オブジェクトは参照によって保存・操作される • 変数名からメモリ上のアドレスにアクセスする • 変数に代入すると参照(アドレス)がコピーされる • 参照先の変更は、同じ参照をしている変数全てに かかる
  25. var myObject = {}; var copyOfMyObject = myObject; myObject.foo = 'bar'; console.log(myObject, copyOfMyObject); // 出力: 参照をコピー 同じ参照 同じ参照
  26. オブジェクトの同値判定 • 同じ参照のときに同値 • 値が同じでも、参照が異なれば同値ではない
  27. var objectFoo = { same: 'same' }; var objectBar = { same: 'same' }; console.log(objectFoo === objectBar); ! ! 別参照 別参照 出力: false
  28. 関数
  29. 関数(Function()) 一般的にはfunction演算子(関数リテラル)を使う 方法で生成する var addNumber = function(num1, num2){ return num1 + num2}; console.log(addNumber(2, 3));
  30. 関数について • 関数は常に値を返す
 return文を記述していない場合などはundefinedが返 される • JavaScriptの関数は「値」として格納できる特徴が る( 第1級関数) • 関数もオブジェクト
  31. 関数の実行方法 • 関数として実行 • メソッドとして実行 • コンストラクタとして実行 • apply()もしくはcall()を使って実行 new Hoge() foo.hoge() hoge()
  32. apply() var myObject = {}; var myFunction = function (param1, param2) { this.foo = param1; this.bar = param2; console.log(this) }; myFunction.apply(myObject, ['foo', 'bar']); console.log(myObject); 配列
  33. apply() var myObject = { myFunction: function (param1, param2) { this.foo = param1; this.bar = param2; console.log(this) } }; myObject.myFunction('foo', 'bar'); console.log(myObject);
  34. call() var myObject = {}; var myFunction = function (param1, param2) { this.foo = param1; this.bar = param2; console.log(this) }; myFunction.call(myObject, 'foo', 'bar'); console.log(myObject); 第二引数以降
  35. call() var myObject = { myFunction: function (param1, param2) { this.foo = param1; this.bar = param2; console.log(this) } }; myObject.myFunction('foo', 'bar'); console.log(myObject);
  36. 関数の即時実行 関数式は関数定義の後に()演算子を付与するこ とによってその場で実行する。 (function(msg){ console.log(msg) })(“Hello”);
  37. 再帰 • 関数は自分自身を呼び出すことができる • 再帰の繰り返しは一般的なコーディングパターン
  38. var countdown = function countdown(num) { console.log(num); num--; if (num < 0) { return false; } countdown(num); }; countdown(5); 再帰 中断
  39. グローバルオブジェクト
  40. グローバルオブジェクト Webブラウザ環境だとwindowオブジェクト グローバルオブジェクト直下に格納されているの が、グローバルプロパティ、グローバル変数 JavaScriptはあらかじめ定義されている関数を幾つ か持っていて、これをグローバル関数と呼ぶ
  41. グローバル関数 decodeURI(encodedURI), decodeURIComponent(encodedURIComponent), encodeURI(uri), encodeURIComponent(uriComponent), eval(x), isFinite(number), isNaN(number), parseFloat(string), parseInt(string, radix)
  42. グローバル変数の作り方 グローバルスコープ下でvar演算子を伴って変数を宣言す る場合、その変数はグローバル変数となる。 var演算子を使用しない場合はグローバルプロパティとし て宣言される。 違いとしてはdelete演算子で消せるかどうか。 delete演算子はオブジェクトプロパティを削除する唯一 の手段。
  43. var a = 10; b = 100; delete a; delete b; グローバル変数 グローバルプロパティ 削除できない 削除できる
  44. this
  45. this 関数が実行される際、thisキーワードの値が設定さ れる。このとき設定される値は、関数を呼び出す オブジェクトへリンク var man = { name: “Haraguchi”, getName: function(){return this.name}; }; manを示す
  46. thisの値はどのように決まる? • 全ての関数に渡されるthisの値は、関数が実行時に 呼び出される際のコンテクストに依存する。 • JavaScriptの「癖」のひとつ
  47. var foo = 'foo'; var myObject = { foo: 'I am myObject.foo' }; var sayFoo = function () { console.log(this['foo']); }; myObject.sayFoo = sayFoo; myObject.sayFoo(); sayFoo(); プロパティに関数指定する オブジェクトメソッド実行 関数実行
  48. 入れ子関数内でのthis 入れ子関数内では、thisはグローバルオブジェクト を参照するという完全に方向を誤った仕様。
  49. var myObject = { func1: function () { console.log(this); var func2 = function () { console.log(this) ; var func3 = function () { console.log(this); }(); }(); } } myObject window window
  50. 入れ子関数内でのthisの保持 入れ子関数内でのthisの値見失わないために、一般 的に入れ子関数からアクセスできるスコープに var self = thisなどで保持して、そのselfを使用する ことでthisを見失うことがない
  51. var myObject = { myProperty: 'I can see the light', myMethod: function () { var self= this; var helperFunction = function () { console.log(self.myProperty); console.log(this); }; helperFunction(); } } myObject.myMethod(); window myObject thisを保持
  52. スコープとクロージャ
  53. スコープとクロージャ コードが実行されるコンテクストにスコープが割 り当てられる。スコープには、下記の三つのタイ プがある。 • グローバルスコープ • ローカルスコープ(関数スコープ) • evalスコープ(非推奨)
  54. スコープ別出力例 var foo = o; console.log(foo); var myFunction = function(){ var foo = 1; console.log(foo); } eval(‘var foo = 3; console.log(foo);’); グローバルスコープ ローカルスコープ evalスコープ
  55. ブロックスコープは無い var foo = 1; if (true) { foo = 2; foo = i; console.log(foo); } fooの値が書き換わる 同じスコープ 同じスコープ
  56. スコープチェーン 変数を参照する時、近いローカルスコープから探し、見つからな かったらグローバルスコープまで る var x = 10; var foo = function () { var y = 20; var bar = function () { var z = 30; console.log(z + y + x); }; }; foo(); 「bar」のローカルスコープ 「foo」のローカルスコープ グローバルスコープ
  57. 静的スコープ • 関数定義時の場所にもとづいてスコープが決定 • thisの決定(実行時)とは、違う • 定義済みの関数を別スコープへ渡しても、スコー プチェーンは変わらない
  58. var parentFunction = function () { var foo = 'foo'; return function () { console.log(foo); } } var nestedFunction = parentFunction(); nestedFunction(); 出力: 'foo' 無名関数を参照 出力: 'foo'
  59. クロージャ クロージャを一言で表すと「スコープチェーンに よって存在する変数への参照を保持している関数」 • カプセル化 • グローバル変数汚染を防ぐ
  60. カプセル化 var countUp = function () { var count = 0; return function () { return ++count; }; }(); console.log(countUp()); console.log(countUp()); console.log(countUp()); 子関数からのみアクセス可能 スコープチェーンをだとる スコープチェーンをだとる スコープチェーンをだとる
  61. クロージャ失敗例 var foo = function () { var funcArray = []; var i; for (i = 0; i < 3; i++) { funcArray[i] = function () { console.log(i); }; } return funcArray; }(); foo[0].(); foo[1].(); 子関数からは共通のiにアクセス 関数の参照を保持
  62. クロージャ成功例 var foo = function () { var funcArray = []; var i; var func = function (i) { return function () { console.log(i); }; } for (i = 0; i < 3; i++) { funcArray[i] = func(i); } return funcArray; }(); 独自に持つローカル変数変数 クロージャを配列に格納
  63. 配列に格納された関数を実行 funcArray[0](); funcArray[1](); funcArray[2](); 出力: 0 出力: 1 出力: 2
  64. まだまだいろいろありますが、 所 は、枝葉の知識。
  65. Cody Lindley 著、和田 祐一郎 訳 開眼! JavaScript―― 言語仕様から学ぶ JavaScriptの本 質
  66. fin. ご静聴ありがとうございました。
Advertisement