JavaScript-OO

5143 ワード

参考資料
Object-Oriented JavaScript,2 nd.Chapter 4
構造体&オブジェクト
コード
function Hero(name, age) {
  this.name = name;
  this.age = age;
}

var hero = new Hero("Tom", 10);
console.log("Name: " + hero.name);
console.log("Age: " + hero.age);
実行結果:
Name: Tom
Age: 10
要点
  • Hero()は構造関数である.コンストラクタは関数である以上、参照することができます.
  • this:クラスメンバー(属性)を定義するために使用されます.
  • new:オブジェクトの作成;
  • コンストラクタは大体頭文字の大文字として決められています.それによって普通の関数と区別されます.
  • 対等なobject lieral定義方法
    下のコードと上の例の効果は同じです.
    var hero = {
      name: "Tom",
      age: 10
    }
    
    console.log("Name: " + hero.name);
    console.log("Age: " + hero.age);
    
    しかし、初期化対象では不便であることが分かった.
    オブジェクトの追加方法
    前のコードに基づいて、メンバーメソッドを追加します.
    コード
    function Hero(name, age) {
      this.name = name;
      this.age = age;
    
      this.debug = function() {
        return "Hero[name:" + this.name + ",age:" + this.age + "]";
      };
    }
    
    var hero = new Hero("Tom", 10);
    console.log(hero.debug());
    
    実行結果:
    Hero[name:Tom,age:10]
    
    等価な書き方
    var hero = {
      name: "Tom",
      age: 10,
    
      debug: function() {
        return "Hero[name:" + this.name + ",age:" + this.age + "]";
      }
    }
    
    console.log(hero.debug());
    
    グローバルオブジェクト
    window
    ここではWEBブラウザだけを討論します.その全体の対象はwindowです.
    var a = 100;
    console.log("a: " + a);
    console.log("a: " + window.a);
    console.log("a: " + window['a']);
    
    ここの三つの訪問方式は同じです.
    つまり、JavaScriptでは、すべてのグローバル変数(関数も変数)がグローバルオブジェクトwindowの属性です.
    window&new
    前のコードを書き換えて、newのキーワードを除いてundefinedを提示します.
    function Hero(name, age) {
      this.name = name;
      this.age = age;
    }
    
    var hero = Hero("Tom", 10); 
    
    
    console.log("Value: " + typeof hero); // Value: undefined
    console.log("name: " + name); // name: Tom
    console.log("name: " + window.name); // name: Tom
    console.log("age: " + age); // age: 10
    console.log("age: " + window.age); // age: 10
    
    // TypeError: hero is undefined
    console.log("Name: " + hero.name);
    
    理由:newを書いていない時、Heroは全体の対象windowの属性だと思って、undefined.また、Hero()関数のthisとは、window全体のオブジェクトのことです.nameとage属性のアクセス方法に注目します.
    newを使うと、新しいオブジェクトが返ってきます.このときのthisは新しいオブジェクトを指します.
    コンストラクタの後ろの物語
    コードだけを与えて、説明はしません.
    妖しいコード
    function C() {
      this.a = 1;
      return {b:2};
    }
    
    var c = new C();
    console.log(c.a); // undefined 
    console.log(c.b); // 2 
    
    擬似コード
    構造関数は次のような過程として理解できます.
    function C() {
      //var this = {};
      this.a = 1;
      // return this;
    }
    
    var c = new C();
    console.log(c.a); // 1 
    
    オブジェクトと参照
    lieral object
    var a = {x:1, y:2};
    var b = a;
    
    function print(a) {
      console.log("(" + a.x + "," + a.y + ")");
    }
    
    function foo(a) {
      a.x++;
      a.y++;
    }
    
    print(a); // (1,2)
    print(b); // (1,2)
    
    b.y++;
    print(a); // (1,3)
    print(b); // (1,3)
    
    foo(a);
    print(a); // (2,4)
    print(b); // (2,4)
    
    new object
    function Point(x,y) {
      this.x = x;
      this.y = y;
    
      this.print = function() {
        console.log("(" + a.x + "," + a.y + ")");
      };
    }
    
    
    var a = new Point(1,2);
    var b = a;
    
    function foo(a) {
      a.x++;
      a.y++;
    }
    
    print(a); // (1,2)
    print(b); // (1,2)
    
    b.y++;
    print(a); // (1,3)
    print(b); // (1,3)
    
    foo(a);
    print(a); // (2,4)
    print(b); // (2,4)
    
    プロトタイプ
    function Point(x,y) {
      this.x = x;
      this.y = y;
    }
    
    Point.prototype.print = function() {
      console.log("(" + this.x + "," + this.y + ")");
    };
    
    Point.prototype.incr = function() {
      this.x++;
      this.y++;
    };
    
    function foo() {
      var a = new Point(1,2);
      a.print(); // (1,2)
      a.incr(); 
      a.print(); // (2,3)
    }
    
    foo();
    
    名前空間
    例1
    var SomeConstants = {
      ONE : 1,
      TWO : 2,
      THREE : 3};
    
    try {
      var a = ONE;
      console.log("a:" + a);
    } catch (e) {
      //Initialize a error: ReferenceError: ONE is not defined
      console.log("Initialize a error: " + e);
    }
    
    var b = SomeConstants.ONE;
    console.log("b:" + b); // b:1
    
    例2
    var NS = NS || {};
    
    NS.SubNS = {};
    
    NS.SubNS = {
      // Constants
      ONE : 1,
      TWO : 2,
      THREE : 3,
    
      // Module variables
      value : NS.SubNS.ONE,
      ob : undefined,
    
      // Functions
      incr: function () {
        value++;
      },
    
      print: function () {
        console.log("value: " + NS.SubNS.value);
      }
    };
    
    // Class
    NS.SubNS.Ctor = function (msg) {
      this.message = msg;
    };
    
    NS.SubNS.Ctor.prototype.setMsg = function (msg) {
      this.message = msg;
    }
    
    NS.SubNS.Ctor.prototype.getMsg = function () {
      return this.message;
    }
    
    NS.SubNS.Ctor.prototype.print = function () {
      console.log("Message: " + this.message);
    }
    
    function foo() {
      NS.SubNS.print(); // value: undefined
      NS.SubNS.value = 100;
      NS.SubNS.print(); // value: 100
    
      NS.SubNS.ob = new NS.SubNS.Ctor("msg1");
      temp = NS.SubNS.ob;
      temp.print(); // Message: msg1
      temp.setMsg("another msg");
      temp.print(); // Message: another msg
    }
    
    foo();