LoginSignup
5
2

More than 5 years have passed since last update.

JavaScriptオブジェクト指向(クラス的なものを作るサンプル)

Last updated at Posted at 2017-02-01

概要

JavaScriptでオブジェクト指向するときのサンプルコードです。

以下のWebサイトを参考にしました。

JavaScript におけるクラスの作成と継承

サンプルコード



(function() {
  // For compatibility
  // IE10以下に対応
  // prototypeとconstructorを設定して継承する
  Function.prototype.inherit = function(base) {
    var f = function() {};
    f.prototype = base.prototype;
    this.prototype = new f();
    this.prototype.constructor = this;
    return this;
  };

  // 名前空間の文字列を「.」で区切る
  function splitNs(nsStr) {
    return nsStr.split(".");
  }

  // 名前空間を作成して末端のオブジェクトを返す
  function ret(nsStr) {
    function ret_helper(rt, symo) {
      if(symo.length > 0) {
        var now = symo.shift();
        if(!(Object.prototype.toString.call(rt[now]) 
            === '[object Object]')) {
          rt[now] = {};
        }
        return ret_helper(rt[now], symo);
      } else {
        return rt;
      }
    }

    return ret_helper(window, splitNs(nsStr));
  }

  // 指定した名前空間のオブジェクトを指定したオブジェクトから参照できるようにする
  window.use = function(nsStr, self) {
    var nss = splitNs(nsStr);
    var obj = self[nss[0]];
    for(var i = 1; i < nss.length; i += 1) {
      obj = obj[nss[i]];
    }
    self[nss[nss.length - 1]] = obj;
  };

  // 名前空間を作成して受け取った関数のthisに登録されたものをすべて作成した名前空間に登録する
  window.ns = function(sym, fn) {
    fn.call(ret(sym));
  };
})();

(function () {
  // 名前空間「rtns.classes」を使用
  ns('rtns.classes', function() {
    // コンストラクタFooを定義
    function Foo() {
      this.x = 2;
    }

    // プロトタイプにメソッドを定義
    Foo.prototype.foo = function() { 
      console.log("foo", this.x); 
    };

    // スタティックメソッドに相当するものを定義
    Foo.staticFoo = function() {
      console.log("static foo");
    };

    // 名前空間に登録して外部から参照できるようにする
    this.Foo = Foo;
  });
})();

(function () {
  // rtns.classes.FooをFooとしてアクセスできるようにする
  use('rtns.classes.Foo', this);

  ns('rtns.classes', function() {
    // Fooを親としてコンストラクタBarを定義
    function Bar() {
      // Fooで定義されているプロパティを作成する
      Foo.call(this);

      // Bar独自のプロパティ
      this.y = 3;
    }

    // プロトタイプを設定して継承する
    // Object.setPrototypeOfが定義されているブラウザではinheritsは不要です
    if(Object.setPrototypeOf) {
      Object.setPrototypeOf(Bar.prototype, Foo.prototype);
    } else {
      Bar.inherit(Foo);
    }

    // Bar独自のメソッドを定義
    Bar.prototype.bar = function() { 
      console.log("bar", this.x, this.y); 
    };

    this.Bar = Bar;
  });
})();

(function() {
  use('rtns.classes.Foo', this);
  use('rtns.classes.Bar', this);

  // Fooのインスタンスを作成
  var f = new Foo();
  // Fooのインスタンスメソッドfooを呼んでみる
  f.foo();

  // Barのインスタンスを作成
  var b = new Bar();
  // Fooで定義されているメソッドをプロトタイプチェーンをたどって呼んでみる
  b.foo();
  // Barで定義されているメソッドを呼んでみる
  b.bar();

  // FooとBarそれぞれのプロトタイプになにが定義されているか確認
  console.log((Foo.prototype.foo)? "Foo has foo" : "Foo has'nt foo");
  console.log((Foo.prototype.bar)? "Foo has bar" : "Foo has'nt bar");
  console.log((Bar.prototype.foo)? "Bar has foo" : "Bar has'nt foo");
  console.log((Bar.prototype.bar)? "Bar has bar" : "Bar has'nt bar");

  // Fooのスタティックメソッドを呼んでみる
  Foo.staticFoo();
})();


5
2
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2