すがブロ

sugamasaoのhatenablogだよ

サイ本 第7章メモ

第7章 オブジェクトと配列

若手IT勉強会 - 第5回勉強会輪講するためのまとめ。これを元に輪講予定です。

JavaScript 第5版

JavaScript 第5版

ちなみに、このまとめは若手IT勉強会 サイ本読書会#4 に参加する当日の8〜11時くらいにまとめた内容です。
もし間違っている箇所等がありましたらご指摘ください!

オブジェクトについて

7.1 オブジェクトの生成
      var obj1 = {}
      var obj2 = new Object() // obj1 と等価
      var obj3 = new Array() // Arrayオブジェクトの生成
  • "{}" の中には プロパティ名:値 というペアで記述することができるよ。 , で複数記載できるよ
      var obj1 = {
        test1:1,       // 数値でも
        test2:"文字列",  // 文字列でも
        test3:{name:"hoge"} // オブジェクトでも入れられる
      }
  • プロパティ名は識別子、もしくは文字列を使うことができるよ
      // 識別子
      var obj1 = {
        test1:1
      }
      // 文字列
      var obj2 = {
        "test1":1
      }

      alert(obj1.test1)  // 1
      alert(obj2.test1)  // 1
      alert(obj1["test1"]) // 1
      alert(obj2["test1"]) // 1
7.2 オブジェクトのプロパティ
  • プロパティへの値の設定は var の宣言等は不要で、そのまま代入できるよ
  • オブジェクトの入れ子も出来るよ
  • ほぼそのままの意味なので他は割愛するよ
      var obj = {}
      obj.name = "test" // 宣言不要で代入できるよ
      alert(obj.name) // "test"
      obj.hoge = {fuga:"piyo"} // オブジェクトの入れ子もできるよ
      alert(obj.hoge.fuga) // "piyo"
7.2.1 オブジェクトプロパティの調査
  • for/in 構文でユーザ定義のプロパティを調べる事ができるよ
      var obj = {
        name:"hoge",
        age:20
      }
      var name = ""
      for(var o in obj) {
        name += o+"\n"
      }
      alert(name) // name\nage\n
  • でもお生憎様! FireBug なら dir 関数でプロパティと値の参照が実現できました!
      var obj = {
        name:"hoge",
        age:20
      }
      dir(obj)// age 20\nname "hoge"
7.2.2 プロパティの存在確認
  • in 演算子で確認することができるよ
      o = {x:10}
      if ("x" in o) o.x = 1 // x プロパティがあれば 1 を代入
      alert(o.x) // 1
      o = {x:10}
      if (o.x !== undefined) o.x = 1 // x プロパティがあれば 1 を代入
      alert(o.x) // 1
  • でもこの方法だと、 o.x = undefined とした場合に正しく動かないので、汎用的にするにはこうした方が良いよ
      o = {x:10}
      if (o.x) alert("hoge") // 表示される
      o = {x:undefined}
      if (o.x) alert("fuga") // 表示されない
      o = {}
      if (o.x) alert("piyo") // 表示されない
7.2.3 プロパティの削除
  • delete 演算子を使う事で削除ができるよ
  • undefinedが代入される、という意味ではないので、for/in や in 演算子でも調べられなくなるよ
      o = {x:10}
      delete o.x
      alert(o.x) // undefined
7.3 連想配列としてのオブジェクト
  • オブジェクトのプロパティは文字列でもアクセスできるよね
  • 文字列でアクセスする場合、実行時に動的に生成することが可能だよね
      var addr = ""
      for (i = 0; i < 4; i++) {
        addr += customer["address" + i] + '\n'; // address0〜address3 までのプロパティの値を取得できる
      }
  • サーバサイドから渡ってきたデータ等、自分自身で把握できないデータに対して、柔軟にアクセスできるね
7.4 Object のプロパティとメソッド
  • すべてのオブジェクト(Date とか Array 等も含めて)の親クラスである Object のプロパティやメソッドについて紹介するよ
7.4.1 constructor プロパティ
  • オブジェクトの生成元のクラスを調べる事ができるよ
      obj1 = {}
      obj2 = new Date()
      obj3 = "test"
      alert(obj1.constructor == Object) // true
      alert(obj2.constructor == Date) // true
      alert(obj3.constructor == String) // true
  • 特定のクラスのオブジェクトを確認する方法
      var o = new Date()
      if ((typeof o == "object") && (o.constructor == Date)) // Date 型独自の処理
      if ((typeof o == "object") && (o instanceof Date)) // 上記と等価
7.4.2 toString()メソッド
  • ちゃんと実装しろよ!(詳しくは 9 章で)
7.4.3 toLocaleString()メソッド
  • toString() の文字列に対して、ローカライズされた文字列を提供するよ
  • JavaScript1.5 では toString と同様に Object クラスに実装されているよ
  • Date 型とかは独自の文字列が実装されてるよ
7.4.4 valueOf()メソッド
  • 文字列以外のプリミティブ型へ変換するのに使われるよ
  • 詳しくは 9 章で!
7.4.5 hasOwnProperty()メソッド
  • 継承したものではないプロパティを持っている場合に true を返すよ
      obj = {hoge:"fuga", piyo:undefined}
      alert(obj.hasOwnProperty("toString")) // false(Objectから継承している)
      alert(obj.hasOwnProperty("hoge")) // true
      alert(obj.hasOwnProperty("piyo")) // true(undefined でも true になるよ)
      alert(obj.hasOwnProperty("aaaaa")) // false(こんなの持ってない)
7.4.6 propertyIsEnumerable()メソッド
  • for/in で調べられるプロパティの場合 true を返すよ
  • ぶっちゃけ、hasOwnProperty と一緒だよ
      obj = {hoge:"fuga", piyo:undefined}
      alert(obj.propertyIsEnumerable("toString")) // false(Objectから継承している)
      alert(obj.propertyIsEnumerable("hoge")) // true
      alert(obj.propertyIsEnumerable("piyo")) // true(undefined でも true になるよ)
      alert(obj.propertyIsEnumerable("aaaaa")) // false(こんなの持ってない)
7.4.7 isPrototypeOf()メソッド
  • このメソッドを呼び出したオブジェクトが引数でしたオブジェクトのプロトタイプオブジェクトである場合に true を返すよ
  • ぶっちゃけ、よくわからないよ><
      obj = {hoge:"fuga", piyo:undefined}
      Object.prototype.isPrototypeOf(obj) // true(Objectのprototype を継承してるよね)
      Object.isPrototypeOf(obj) // false
      obj.isPrototypeOf(Object.prototype) // false

配列について

7.5 配列
  • 普通の Object と似ているよ
  • 実のところ、オブジェクト + αな機能が追加されているだけだよ
  • + αの部分っていうのは length プロパティとかだよ
  • 値にはプリミティブ型以外にもオブジェクトをそのまま入れる事ができるよ
      var ary1 = []
      var ary2 = [11,12,13] // [0]〜[2]に 11 〜 13 の値が入ってる
      var ary3 = [{hoge:"fuga"}, 1]
      alert(ary3[0].hoge) // fuga
      var ary4 = [,] // 1個の空の要素を持つ配列
      var ary1 = new Array() // 空の配列
      var ary2 = new Array(1, 2, "str")  // 初期値を代入する
      var ary3 = new Array(10) // 10 個の空要素の配列を生成する
7.6 配列の要素の読み書き
  • [] 演算子でアクセスできるよ
  • 添字には変数も使えるよ
  • 配列の添字としては整数値しか使えないよ。負数や論理値を使った場合は文字列に変換されて、その文字列のプロパティとして扱われるよ
      ary = []
      ary[0] = 10
      alert(ary.length) // 1
      i = 1
      ary[i] = 100
      alert(ary.length) // 2
      alert(ary[0]) // 10
      alert(ary["0"]) // 10(文字列でも整数値ならアクセスできるよ)
      ary["hoge"] = 199
      alert(ary.length) //2 ("hoge"はプロパティなので配列としてはカウントされていない)
7.6.1 配列の要素の追加
  • 添字に対して追加していけば追加されるよ
  • 通常のオブジェクト等に対しても添字を使って追加とかできるけど、Array オブジェクトじゃないと要素数が取れないよ
      ary = new Array()
      alert(ary.length) // 0
      ary[0] = 11
      alert(ary.length) // 1
      obj = {}
      alert(obj.length) // undefined
      obj[0] = 10
      alert(obj.length) // undefined
7.6.2 配列の要素の削除
  • delete 演算子では値は削除できても配列の要素自体が削除できないよ
  • shift や pop, slice 関数を使って削除するよ
7.6.3 配列の長さ
  • Array() や [] で生成されたオブジェクトは length プロパティを持っているよ
  • length プロパティは配列の大きさを保持しているよ
  • 厳密に言うと、配列の添字の最大値 + 1 を値として持っているよ
      ary = new Array()
      alert(ary.length) // 0
      ary[10] = 10
      alert(ary.length) // 11
7.6.4 配列の要素の巡回
  • length プロパティでアクセスできるよ
      var ary = ["hoge", "fuga", "piyo"]
      for (var i = 0; i < ary.length; i++) {
        alert(ary[i])
      }
  • 0から始まる事が保証できない場合は下記のようにすると良いよ
      var ary = [, "fuga", "piyo"]
      for (var i = 0; i < ary.length; i++) {
        if(ary[i]) alert(ary[i])
      }
7.6.5 配列の長さの変更
  • length プロパティは読み書き可能だよ
  • length プロパティを短くすると、範囲外になった要素は破棄されるよ
  • length プロパティを長くすると、値は未定義として追加されるよ
      var ary = ["hoge", "fuga", "piyo"]
      alert(ary.length) // 3
      alert(ary[ary.length-1]) // piyo
      ary.length = 2
      alert(ary.length) // 2
      alert(ary[ary.length-1]) // fuga
      alert(ary[2]) // piyo があったけど undefined
7.6.6 多次元配列
  • 配列の配列として表現できるよ
  • ary[x][y] みたいにすれば良いよ
7.7 配列のメソッド
  • ry
7.7.10 JavaScript 1.6で追加されたメソッド
  • Firefox 1.5 では実装されているけど、標準かされている訳ではないので、汎用的ではないよ。なので(ry
7.8 配列のようなオブジェクト
  • 配列は length プロパティが特別な働きをすることが他のオブジェクトとは違うところだよ
  • 配列に新しい要素が追加されると length プロパティも更新されるよ
  • length プロパティを変更することで要素数や値も変更されるよ
  • length プロパティを持っていて、その値をインデックスとしてしか使わないロジックならば”配列ではなくても”配列の如く扱えるよ
      var a = {}
      var size = 10
      for(var i = 0; i < size; i++) {
        a[i] = i
      }
      a.length = size

      // 要素を走査するような処理ならば配列と同じように扱える
      var total = 0
      for(var i = 0; i < a.length; i++) {
        total+= a[i]
      }
      alert(total)
  • 配列のようなオブジェクトとして "Arguments" や document.getElementsByTagName()の戻り値等があるよ

おしまい