読者です 読者をやめる 読者になる 読者になる

JavaScriptでオレオレクラス実装 その2

こんばんは、south37です。
前回、思いつきでJavaScriptにおけるクラス実装とかしちゃった訳ですが、思った以上に楽しかったので続きを書いちゃいました。引き続き誰得回で申し訳ないです。

継承(っぽいもの)を実装してみた

って訳で、表題の通り継承っぽいものを実装してみました。inheritsでなくincludeってプロパティ名にしてるのは、胸を張って継承と呼べる出来じゃ無い気がするからです。

_ = require('underscore')

Class = {}
Class.def = (classSpec) ->
  for name, specs of classSpec
    inheritedSpecs = {}
    if specs['include']?
      inheritedName = specs['include']
      inheritedSpecs = _.extend inheritedSpecs, Class[inheritedName].specs

    allSpecs = _.extend inheritedSpecs, specs

    Class[name] = ->
      obj  = {}
      self = {}

      if allSpecs['init']? and typeof allSpecs['init'] is 'function'
        allSpecs['init'].apply(self, arguments)

      for key, value of allSpecs
        if key not in ['include', 'init'] and typeof value is 'function'
          methodName = key
          method     = value

          obj[methodName] = ->
            method.apply(self, arguments)

      return obj

    Class[name].specs = allSpecs

Class.def 'Quo':
  init: (status) ->
    this.status = status
  status: ->
    this.status

Class.def 'ChildQuo':
  include: 'Quo'

Class.def 'GrandChildQuo':
  include: 'ChildQuo'

myQuo = Class.Quo 'OK'
console.log myQuo.status() //OKと出力

myGrandChildQuo = Class.GrandChildQuo 'OK'
console.log myGrandChildQuo.status() //OKと出力

とりあえず、QuoをincludeしたChildQuoをincludeしたGrandChildQuoクラスでインスタンスを生成するとちゃんとQuoで定義したstatusメソッドが使える事が確認出来ました。本当は、継承した先のメソッド内でsuperで継承元のメソッドが使える、みたいな感じにしたかったんですが、こちらで指定した変数名を使えるようにする方法が分からなかったので、諦めました。。。

追記

CoffeeScript使っておきながら今気づいたんですが、CoffeeScriptの中ではもっとかっこいい感じでclass定義が出来るっぽいですね。まあ、考える事は同じというか、先を越されたというか、ちょっとへこみます。。。あと、CoffeeScript実装した人は絶対にrubyistだろうなって思いました。