ECMAScript と OOP パラダイム、それに ES.next の議論中 OOP 周りのシンタックス

JavaScript Advent Calendar 2011 (オレ標準コース)4日目の id:oogatta です。どうもどうも、いやどうも。

最近丁度 ES Wiki を眺めていて、面白いことになってるなあ。変態的なことになってるなあ。と楽しく見ていた OOP パラダイム周りのいくつかの手法(定義、継承、 mixin 、 trait )について、 ES.next または Harmony で議論されているものをご一緒に調べながらご紹介したいと思います。

ECMAScript3

さて、復習としてまずは ES3 での OOP パラダイムの実装についてですが、これはもう Dmitry 先生の ECMA-262-3 in detail. Chapter 7.1. OOP: The general theory. を読んでくださいというか、気持ちよく丸投げしたいところですが、翻訳すると言ってまだそこまでたどり着いてないのが誰あろう私ですので、ざっくり復習してみます。

定義/生成
function Unko(a,b) {
    this.a = a;
    this.b = b;
}

var unko = new Unko(10,20);

unko.a; //10
unko.b; //20

今更書くまでも無かったかも知れませんが、これがコンストラクタを用いた、教科書的な、「半分クラスっぽい」 OOP の実装によるオブジェクトの生成です。でも最近は、プロトタイプベースであることに立ち返って、

var unko = {
    a : 10,
    b : 20,
    method : function method() { //... }
};

とオブジェクトリテラルから直接オブジェクトを生成してしまったり、もう少しカプセル化を意識して

function Unko(arg_a,arg_b){
  var a  = arg_a;
  var b  = arg_b;
  var _c = 30;

  var method = function method() {
    return a + b + _c;
  };

  return {
    a : a,
    b : b,
    method : method
  };
}

var unko = Unko(10,20);

コンストラクタではなく一般の関数を用いてこんなことをやったりするようになりました。それもこれも、以下に挙げるようにコンストラクタベースでのプロトタイプ継承が今一宣言的でない(綺麗でない)ということや、スタティッククラスモデルとは違い、「継承」が委譲ベースであることと、「継承」という OOP 手法が若干時代遅れになってきたことが大きいのだと思います。スタティッククラスモデルの言語でも、結構クラスの継承を用いずにコンポジションによる委譲を用いたりする場面が増えているのではないでしょうか?。

継承

とはいえ、実際に継承を用いる場面は無くはありません。自分でこうしたコードを書かなくても、フレームワークがやってくれたりしているかもしれません。 ECMAScript における継承といえば、まさにこうです。

function SugoiUnko(a,b){
  // ...
}
function Unko(a,b,c) {
  // ...
}

Unko.prototype = new SugoiUnko();

var unko = new Unko();
unko.constructor = Unko;

コンストラクタの prototype プロパティに委譲先オブジェクトを代入する方法で、先に述べたとおり、設計図となるクラス間に親子関係を持たせるスタティッククラスモデルとは異なり、実際的には prototype チェーンを用いた委譲モデルであると捉えた方が素直かもしれません。これが ES3 のみならず、今も続く ECMAScript の継承の実装です。

この「 prototype チェーンを用いた暗黙的な委譲モデル」がどうも明示的で無いと意識的・無意識的に感じてらっしゃる方は、もっと明示的なコンポジションを用いているかもしれません

var superUnko = {
  unko : unko,
  a : 10,
  b : 20,
  method : function() {
    return a + unko.method();
  }
};
var unko = {
  method : function() { //... }
};

この委譲モデルに、先のカプセル化の例で用いたオブジェクト型の関数、そしてより関数型パラダイムであることをフルに活かすともっと魔術的なことができるわけですが、そうした例は今回は割愛します。なぜなら僕自身がそういうコードが苦手だからです!

mixin

さて mixin です。一口に mixin と言っても、おおざっぱな分け方として dynamic mixin と static mixin があります。乱暴な言い方をすれば、オブジェクト(インスタンス)にオブジェクトを mixin するのか、クラスにクラスを mixin するのか、です。オブジェクトが動的( dynamic )であり可変( mutable )である ECMAScript なら、 dynamic mixin がおなら程度に簡単であることがわかります。

function mixin(target,source){
  for ( key in source ) {
    if ( source.hasOwnProperty(key) ) {
      target[key] = source[key];
    }
  }
}

var unko   = { a:10, b:20 };
var osikko = { c:30, d:40 };

mixin(unko,osikko);

unko.d; //40

これをわざわざ OOP 手法の一つとして取り上げることが不思議なくらい、 ECMAScript にとってはごく自然な計算です。

trait

trait です。 trait は…。実際にまだ私も業務で ECMAScript 上で実際に使ったことはありません。そもそも trait って何ぞ。という僕のような人間が纏めると…。

  • クラスによる型の強制は大袈裟だし、クラスよりもうすこし小さい粒度で、コードの再利用を、 mixin よりは構造化されて綺麗に、やりたいな、という時に使えます。
  • そもそもスタティッククラスモデルではない無い言語で、「より良い」 mixin 的な感覚で使えます。
  • インターフェースや継承クラスの継承による型の保証に比べて、型ではなくよりふるまいに注目してオブジェクトの組み立てを行う為、ダイナミックな言語、ダックタイピングに向いています。
  • mixin よりは構造化?: trait を多層にコンポジションできます。 trait を mixin ( trait を実装)する際に、プロパティに別名を付けたり、実装したくないプロパティを除外するなど便宜を図れます。コンポジション時に依存する外部メソッドを require として宣言しておけます。

こんな感じです。説明だけだとよく分からないと思います。良い感じの static mixin だと思っていただければと思います。そうなんです。 static mixin なんです。これがちょっと書式をややこしくする原因になっているのですが、 ES3 のコンテキストで trait を実装しようとするとそれだけで1記事どころか10記事くらいになってしまいますので、とりあえず、 trait.js というライブラリのサンプルコードを見ていただくということでお茶を濁します。

Enumerable にする(機能をもった) trait 。

var EnumerableTrait = Trait({
  // この trait は、これらのプロパティが実装先で他の trait またはクラスによって提供されていることを要求する。
  forEach: Trait.required,

  // この trait は、これらのプロパティを提供する。
  map: function(fun) {
    var seq = [];
    this.forEach(function(e,i) {
      seq.push(fun(e,i));
    });
    return seq;
  },
  filter: function(pred) {
    var seq = [];
    this.forEach(function(e,i) {
      if (pred(e,i)) {
        seq.push(e);          
      }
    });
    return seq;
  },
  reduce: function(init, fun) {
    var result = init;
    this.forEach(function(e,i) {
      result = fun(result, e, i);
    });
    return result;
  }
});

EnumerableTrait を mixin (実装)するオブジェクト 。

function makeInterval(min, max) {  
  return Trait.create(Object.prototype,
    Trait.compose(
      EnumerableTrait,
      Trait({
        start: min,
        end: max,
        size: max - min - 1,
        toString: function() { return ''+min+'..!'+max; },
        contains: function(e) { return (min <= e) && (e < max); },
        forEach: function(consumer) {
          for (var i = min; i < max; i++) {
            consumer(i,i-min);
          }
        }
      })));
}

trait を実装することで、Enumerable な操作ができるようになりました。

var i = makeInterval(0,5);
i.start // 0
i.end // 5
i.reduce(0, function(a,b) { return a+b; }) // 0+1+2+3+4 = 10

どうでしょうか。実現されることと手法は素晴らしいですが、記法だけ見るとこれはやっぱり魔法じゃあ無いですか?。というわけで、 ES.next ではこれをより宣言的にする試案が出ていますので後でご紹介します。

各種ライブラリ

さて、ここまで裸の ECMAScript3 を使って( trait だけサボりましたが) OOP のいくつかの手法についてコードを見てきました。しかしまあ実際上記のようなコードを自分で書く場面は少ないのでは無いでしょうか?。世には既に多くの OOP パラダイムをより宣言的に実装しようと試みたフレームワークがたくさんありますので、一旦現実に立ち返って、ここで各種フレームワークのコードを見てみたいと思います。

Prototype

クラスライクな OOPJavaScript に持ち込んだ代表格、 Prototype.js です。

var SuperUnko = Class.create({
  initialize : function() {
    // ...
  },
  method : function method() {
    return "test";
  }
});

var Unko = Class.create(SuperUnko,{
  method : function method($super,a) {
     return $super() + a;
  }
});

var unko = new Unko();
unko.method("dayo-n"); // "testdayo-n"

十分に見栄えが良くなりました。 Object.extend を使えば dynamic mixin も簡単にできます。

mootools

同じく mootools も OOP パラダイム実装を掲げたフレームワークです。

var SuperUnko = new Class({
  initialize : function() {
    // ...
  },
  method : function method() {
    return "test";
  }
});

var Unko = new Class({
  Extends : SuperUnko,
  method : function method(arga) {
    return this.parent() + a;
  }
});

var unko = new Unko();
unko.method("dayo-n"); // "testdayo-n"

ほとんど一緒ですが、スーパークラスを Extends プロパティの値とするところが、より宣言的でどうせならここまでやりたいと個人的には思います。

SproutCore

今もそうなのかは知りませんが、 Apple と言えば SproutCore です。 SproutCoreOOP を意識しています。使ったこと無いのでコードは怪しいですが…(ちなみにこれまでのコードも全く実装系で実行してためしていませんのでご了承…)。

var SuperUnko = SC.Object.extend({
  method : function method () {
    return "test";
  }
});

var Unko = SuperUnko.extend({
  method : function method (a) {
    return sc_super() + this.get("separator") + a;
  }
});

var unko = Unko.create({
  separator : "/"
});

unko.method("dayo-n"); // "test/dayo-n"

すべてのクラス(のようなもの)は SC.Object を継承することで実現しています。最後に create メソッドでインスタンスを生成します。インスタンス生成に通常の new オペレータを使えないところなどは、少し迂遠かもしれません。

JavaScriptMVC

僕が個人的に愛して止まない JavaScriptMVC です。もう3年前のことになりますが、勤務先友人リスト機能はまるごと JavaScriptMVC で作りました。その後社内の開発者のみなさまには大変不評です。ありがとうございます。ちなみに勤務先では、今は brook という自前のフレームワークを使っています。

さて、当時から比べるとかなり様変わりしてしまった JavaScriptMVC ですが、当時から変わらないのは、いろいろな単体で使えるライブラリを組み合わせてフレームワークとする方針です。 OOP パラダイムの実装はどうしているかというと、なんと jQueryプラグインを書いています。 jQuery.Class です。

$.Class("SuperUnko",
/* スタティックプロパティ */
{
  A : 10
},
/* プロトタイププロパティ */
{
  method : function method() {
    return "test";
  }
});

SuperUnko("Unko",{
  method : function method(a) {
    return this._super() + a;
  }
});

unko = new Unko();
unko.method("dayo-n"); // "testdayo-n"

クラス(コンストラクタ)のスタティックプロパティを定義時に一緒に定義できることと、サブクラスの作り方が面白いですね。これ勝手に Unko っていうクラスが window の下に作られちゃうんでしょうか。怖いですね。いや、昔から JavaScriptMVC はこんな感じだったと思います。宣言的という意味では、プロシージャルな面が見えなくなっている分、より宣言的かも知れません。他のライブラリとは、明らかに混ぜるな危険です。

qooxdoo

qooxdoo もまた OOP パラダイムを標榜するフレームワークです。なんて読むのか分かりませんが。

qx.Class.define("com.oogatta.sample.SuperUnko",
{
  statics : {
    A : 10
  },
  members : {
    method : function method () {
       return "test";
    }
  }
});

qx.Class.define("com.oogatta.sample.Unko",
{
  extend : com.oogatta.sample.SuperUnko,
  members : {
    method : function method(a) {
      return this.base() + a;
    }
  }
});

var unko = new com.oogatta.sample.Unko();
unko.method("dayo-n"); // "testdayo-n"

これは面白いですね!。名前空間の管理(モジュラライズ)とクラスの定義継承を同じレイヤーで扱うようにしているというのはなかなかユニークです。これも当然 window にどかんとプロパティを作るのでしょうか。ちなみに、なんと、 static mixin いや、半ば trait の実装もあります。

qx.Mixin.define("com.oogatta.sample.MMixin",
{
  includes : [com.oogatta.sample.MSuperMixin], // super mixin
  members : {
    method2 : function method2 () {
    }
  }
});

qx.Class.define("com.oogatta.sample.Unko",
{
  includes : [com.oogatta.sample.MMixin],
  members : {
    // ...
  }
});

var unko = new com.oogatta.sample.Unko();
unko.method2();

ドキュメントには「 ruby の mixin から持ってきた」と書いてあります。自分は ruby に全く明るくないのですが、どうなのでしょうか。かなりよく出来ていると思います。

Ext JS

どうやら、 UI ウィジェット構築を指向するフレームワークは、 OOP に関してかなりアグレッシヴになる傾向にあるようです。歴史ある Ext JS ですが、これを書くに当たりバージョン4を見てみたら、ほぼ qooxdoo に似たような名前空間/mixinな OOP 実装になっていました。

Ext.define("com.oogatta.sample.SuperUnkoSupporter" {
  // ...
});

Ext.define("com.oogatta.sample.SuperUnko", {
  requires : ["com.oogatta.sample.SuperUnkoSupporter"]
  method : function method () {
    // ...
  }
});

Ext.define("com.oogatta.sample.Unko", {
  alias : ["Unko"],
  extend : "com.oogatta.sample.SuperUnko",
  method : function methdd (a) {
    return this.callParent() + a;
  }
});

Ext.define("com.oogatta.sample.Timpo" {
  mixins : {
    unko : "com.oogatta.sample.Unko"
  }
});

static mixin ですね。さらに require や alias といった OOP パラダイムと言うよりはモジュール管理に必要な要素も揃っています。僕は個人的にこうした宣言的な(設定風な)クラスの生成は大好きなのですが、 ECMAScript の特性から離れすぎているのでは?。という議論もあるかと思います。 UI Widget のような、明らかに「継承」という仕組みが有効に働く局面もあれば、そうでない場面もあるわけで、マルチパラダイムな言語であるからこそ、使い分けが重要になってくるのかなと思います。

ECMAScript5

…。え?。ライブラリの紹介の流れで ECMA5 ?。という感じかと思いますが、そうなんです。一昨年(もう一昨年)の冬に策定された ECMAScrip5 ですが、どちらかといえば、「(動的で可変な)オブジェクトに注目してこれを上手に扱うための機能」が追加されたという趣で、シンタックスや、 OOP パラダイムのこれまで取り上げたような多少抽象度の高い手法については、ほぼ何も、目新しい面はありませんでした。例えば Object.create メソッドも、

function SuperUnko() {
}

var unko = Object.create(new Unko(), {
  // ...
})

インスタンスを生成するものですから、似ているようで、 Prototype.jsClass.create とは全く異なるものです。

同様に Object.defineProperties でも、 [[Writable]][[Enumerable]] といったこれまでの内部属性値を設定できるようになったという話であり、オブジェクトそのものに注目していることがよく分かります。

これらの追加実装を利用すれば、これまで紹介したようなフレームワークの開発者が、より堅牢なフレームワークを構築できるようになった、ということであり、言い過ぎかも知れませんが、一般の開発者にはあまりメリットは無かったのでは無いでしょうか。それが言語仕様のあるべき姿だ、と言われると、そうなのですが。

というわけで、やっと ES.next / Harmony の話に移ります。

ES.next / ECMAScrip6 / Harmony / Strawman

はじめに

最新の JavaScript/ECMAScript の動向を知ろうとすると ES.next やら Harmony やら、この二つの言葉をよく耳にすると思います。これらが ECMAScript の次期バージョンとどう関係するかというと、すべて ES Wiki にあるのですが…、

ES.next
「おそらく」 ECMAScript6 になるもの。その仕様のすべてがバージョン6に含まれるのか、そもそもバージョン6として出すのか、その辺は完全に決定ではないらしい。仕様の現在のドラフトは一月おきくらいに PDF になって公開中。標準化団体 ECMAECMAScript の仕様策定に当たっている TC39 という委員会が作ってます。
Harmony
ECMAScript4 の失敗が明確になったとき、次期 ECMAScript をみんなで仲良く作りましょうということで掲げられたざっくりとした未来の仕様群。初期はこれ全体が ECMA6 になる予定だったらしいが、そのうち話が大きすぎると気づいて ES.next を抽出して明確化した(ただし ES.next は依然として Harmony の部分集合であることに注意)。今でも Harmony 向けに採択された仕様が ES.next に取り込まれたり、「やっぱりこれは次の次まで置いておこう」と保留になったりしている。 Harmony の proposal として取り上げられたものは逐一 wiki に纏められています。
strawman
TC39 に取り上げられる前に、仕様はコミュニティでももちろん議論される。 es-discuss ML がその主な場所になるが、その際に試案として議論される仕様やサンプルコードが公開されるのが strawman 。ここから、 TC39 によって選ばれしもの達が Harmony の proposal に進むようです。

というわけで、実際に「 ECMA6 に採択されるものだけ知りたい」ということになると、 ES.next の仕様ドラフトの内容のみを見ていけばいいわけですが、いかんせん JavaScript の父であり TC39 のお頭でもある Brendan Eich さんがいろんなところで「これが未来の JavaScript だ」とかなんとか言いながら Harmony や果ては strawman の内容までプレゼンで紹介したり、 Firefox で先行実装したりするものだからさあ大変。

ひょっとしたら今 ES.next のドラフトに含まれている仕様も落とされるかもしれませんし、逆に strawman に上がっている内容が取り込まれるかも知れません。よく分かりません。なので、ここでは strawman の試案まで含めて、ごくごく個人的な観点から、面白そうな OOP のシンタックス、実装をご紹介します。

class ( ClassDeclaration & ClassExpression ) / Harmony

ES3 の最初の最初にご紹介した、一番プレーンなコンストラクタからのオブジェクトの生成と、 prototype オブジェクトを用いた継承のコードがありましたが、やはりあれでは、プログラマの意図を表現するのに抽象度が足らない、具体的・手段的・命令的に過ぎるとみんなが思いました。そこであくまでシンタックスシュガーとして、 ClassDeclaration と ClassExpression が用意されようとしています。

class SuperUnko {
  constructor(a, b) {
    public a = a;
    public b = b;
  }
  public method () {
    return "test";
  }
}

class Unko extends SuperUnko {
  constructor(a, b) {
    super(a,b);

    private c = a + b;
  }
  public method (test) {
    return super.method() + test;
  }
}

var unko = new Unko();
unko.method("dayo-n"); // "testdayo-n"

これまでの、 ECMA3 及び各種ライブラリの実装と比べてどうでしょうか。めちゃくちゃすっきりして宣言的では無いですか?。しかもプロパティの private/public まで宣言してカプセル化も一目瞭然です。

あくまで prototype を使った継承に関する新しいシンタックスですので、 Flash-er の方には ActionScript2 でまさに見たことがあるのでは無いでしょうか。あれです。

もちろんこれが「 JavaScriptJava になる必要は無い」というヒステリックな反応を巻き起こしたりもしています。だったらおまえらはそのまま原始人みたいな魔術的なコード書いてりゃいいだろうが!。と私は薄々思っております。自分しか書けない複雑なコードが好きだという変わった人も世の中にはいるものです。

<| operator ( Object Literal Extensions ) / ES.next, Harmony

そんな魔法使い志望の方々のために、実に嫌々ながらご紹介します。なんともう ES.next のドラフトにも入ってしまっている、 Object リテラル拡張の一環、 <| operator です。

ES5 での Object.create 実装の延長線上にあります。

var unko = Object.create(superUnko, {
  a : {
    value : 10,
    enumerable : false,
    writable : false
  },
  b : {
    value : 20,
    enumerable : false,
    writable : true
  },
  method : {
    value : function() {
      return "test";
    }
  }
});

これを、なんと、神も恐れぬ所業で

var unko = superUnko <| {
  a := 10,
  b : 20,
  method (test) {
    return super.method() + test;
  }
}

このように短く書いてしまえるのです。ああ、人間の業とはなんと恐ろしい!!。 <| operator だけではなくて := operator だったり、 method の簡略書式などが導入されています。すごいです。力一杯驚きます。

とはいえ、 <| は、 UML のクラス図の汎化の矢印(△)を表した operator です。そう考えると比較的すとんと落ちてきます。クラス・コンストラクタでは無く、直接オブジェクトに注目しながら継承や組み立てを行っていく上で、案外悪くないシンタックスなのかもしれません。

実は、単に Object.create の簡略記法で終わらないところがこの <| operator の怖いところです。今提案されている production を見てみましょう。

MemberExpression : ...
  MemberExpression <| ProtoLiteral 

ProtoLiteral : 
  LiteralObject 
  LiteralValue 

LiteralObject : 
  RegularExpressionLiteral 
  ArrayLiteral 
  ObjectLiteral 
  FunctionExpression 

LiteralValue : 
  NumberLiteral 
  StringLiteral 
  BooleanLiteral

ああなんと言うことか(だんだん感情的になってきました)、 <| operator の RHS には、リテラルならなんでも取れるのです。サンプルコードでは、

MyObject.prototype <| {a:1,b:2}
appBehavior <| [0,1,2,3,4,5]

こんなことをしています。これで生成されるオブジェクトは、 <| operator の LHS を [[Prototype]] に代入した RHS です。つまりリテラル値という値に対し、直接拡張したいふるまいをアサインして拡張する、そういうイメージです。

ちなみに <| operator は、 LHS と RHS に何が来るかで機序( semantic )がその都度変わります。これも大いに狂ってるところです。上の production をよく見てください。 RHS に FunctionExpression も取ることが出来ます。サンプルによればこうです。

let ExtendedDate = Date <| function (...args) {super.constructor(...args};

ああもう。えらいことになってしまいました。この新しく作られた ExtendedDate オブジェクトは、 RHS の関数の prototype ( [[Prototype]] じゃないですよ)を Date.prototype に取った新しいオブジェクトです。

機序だけを考えるとややこしいですが、やりたいことは、 Date 型を右辺の新しいふるまいで拡張することです。

ちなみにですが、 Object.create の簡略形として <| があるとすれば、 Object.defineProperties にはこんな簡略形が用意されるようです。

Object.defineProperties(obj,{
  a : {
    value : 10,
    enumerable : false,
    writable : false
  }
  b : {
    value : 20,
    enumerable : false,
    writable : true
  }
});

こうなります。

obj.{a:=10,b:20};

これまた ES5 で導入した実装をより簡略化した記法です。

これら class の記法と <| operator 二つを合体するとどんなことになるか…?。そんな試案が strawman に上がっています。

The class operator / strawman

「まどろっこしいこと言わずに、 class を operator にしちゃったらどうだい?」という試案です。

let Unko = class SuperUnko <| {
  a:=10,
  b:20,
  method (test} {
    return test;
  }
};

なんだかもう分かりません。普通に書いたら駄目なんでしょうか。 operator なのでさらにコードのあらぬところに顔を出せるわけですが、興味がある方はリンク先の試案をご参照ください。

Class Definition Pattern Using Object Extension Literals / Harmony?

<| operator と、拡張された . operator で、十分にクラス定義が出来るのでは?。と考えた方もいらっしゃいます。 Allen Wirfs-Brock さんです。

const className = superClass <| function() {
  // コンストラクタ
  super.constructor();
  this.{
    // インスタンスプロパティ
    a := 10,
    b : 20
  };
}.prototype.{
  // プロトタイププロパティ
}.constructor.{
  // スタティックプロパティ
};

なんだか JavaScriptMVC の例に似てきました。これがあれば ClassDeclaration いらないんじゃない?。ということで es-discuss で大いに物議を醸したようです。ご判断はみなさまにお任せいたします。

trait / strawman

最後にご紹介するのは ClassDeclaration / ClassExpression をさらに拡張し、 trait を実装しようとする試案です。

サンプルをそのまま持ってきてみます。

  trait ColorTrait {
    new(rgb) {
      public get rgb() { return rgb; }
    }
    public equals(col) { return col.rgb.equals(this.rgb); }
  }
  class Circle {
    mixin Magnitude;
    mixin ColorTrait with equals as equalColors; // 名前変更で衝突回避
    mixin BareCircle;
    new(center, radius) {
      mixin ColorTrait(rgb);
      mixin BareCircle(center, radius);
    }
  }
// または
  class Circle {
    mixin Magnitude;
    mixin ColorTrait without equals;                  // 除外で衝突回避
    mixin BareCircle;
    new(center, radius) {
      mixin ColorTrait(rgb);
      mixin BareCircle(center, radius);
    }
  }
// または
  class Circle : ColorTrait {                    // オーバーライド
    mixin Magnitude;
    mixin BareCircle;
    new(center, radius) {
      super(rgb);
      mixin BareCircle(center, radius);
    }
  }

trait 宣言で trait を定義して、 mixin 宣言でそれを実装する。プロパティエイリアスや除外も出来て trait として一人前です。これがあるとすごく嬉しいですね。多段や多重の継承といった危険な術法が、これだけ宣言的な表記を用いることで要らなくなるとすれば、かなり喜ばしいことです。

おわりに

というわけで、駆け足で ECMAScriptOOP パラダイム実装について触れてみました。 Harmony に至っては未だに盛んに議論が交わされているものばかりですので、あまりぎょっとせずに冷静に見つめるのが良いと思います。でも、 <| operator はもうドラフトに入っていますが…。

あれ、多重継承は?。多段継承は?。ポリモーフィズムは?。とお気づきの賢明な読者の方には、どうか、続きを書いてくださいとお願いして、この場を閉めたいと思います…。

ありがとうございました。